Executive Summary

The evolution of South Africa’s strategic policy directions was analysed through the application of natural language processing (NLP) techniques to the texts of the Reconstruction and Development Plan (RDP), Growth, Employment And Redistribution (GEAR), the Accelerated and Shared Growth Initiative South Africa (AsgiSA), the New Growth Path (NGP), and the National Development Plan (NDP).

All documents emphasise the role of governance and public sector for economic development. RDP is emphasising the terms related to democratisation and reconstruction, with less importance shown to issues related to economic growth. This changes in GEAR where issues of fiscal policy and stability, together with employment related issues, come to the fore. AsgiSA brings up terms related to projects and institutions with additional emphasis on agriculture. NGP is more centrally concerned with economic growth, aspects of green economy, and employment issues, particularly among youths. The most recent NDP is interesting in that it has relatively fewer mentions of economic growth, employment, and real sector related terms. What sets NDP apart from previous development plans is its emphasis of health and low carbon economy, and corruption related issues.

In statistical, probabilistic topic modeling analysis, nine topics are identified across all development plans. In the decreasing order of proportion of development plans’ documents, the topics relate to: climate change and resources; green economy; corruption and security; health; skills and training; economic growth; fiscal policy and macroeconomy; reconstruction and democracy; and education. Supporting exploratory study results, probabilistic topic modeling analysis suggests that health, climate change and resources, and corruption and security are more prominent in NDP compared to other development plans. Skills and training is covered more in AsgiSA and marginally so in NGP, compared to other development plans. NGP also gives more prominence to green economy topic compared to other development plans. Fiscal policy and macroeconomy has higher coverage in GEAR. And, as expected, reconstruction and democracy are more covered in RDP. Analysis of the relationship between topics suggests that topics related to education and green economy are more likely to be covered in the same document. Similarly, economic growth and fiscal policy and macroeconomy topics appear in the same development plans.

One important issue is the diversity of content in development plans over time. We observe a dramatic increase in size of the plans over time. This is particularly true for NDP, which stands at 162,056 total words and 6,627 sentencces. The number of distinct words in NDP is 32,965. This is more than three times higher than the second largest number in NGP and almost twenty times higher than in AsgiSA. That may reflect more diverse issues that are being discussed in NDP. Topic modeling results highlight the same issue. From nine topics identified NDP has a statistically significant, positive effect on four topics, while AsgiSA, GEAR, RDP have one statistically significant effect each and two for NGP.

Employment and jobs are prominent in the development plans. From probabilistic topic modeling we identified one topic (out of nine) focusing on issues of jobs and employment. More generally, employment related term is the 8th most frequent word in the whole corpus. Top 50 words also contain references to work, jobs, and labour.

In the analysis of National Budget Reviews we focused on two concepts (output stabilisation and credibility), defined through a set of keywords provided by the World Bank. Total mentions of both concepts in NBR corpus was traced since 1998 until 2017. “Output stabilisation” peaked in the 2009 NBR, while “credibility” reached its peak in 2013. Although “credibility” was generally more often mentioned in NBR over time, there has been an upswing in mentions of “output stabilisation” since 2016 and overtaking “credibility” in the 2017 NBR.

Overview of the project

The World Bank Group (WBG) twin goals of ending extreme poverty and promoting shared prosperity reflect a new global landscape: one in which developing countries have an unprecedented opportunity to end extreme poverty within a generation. The WBG will face traditional and new challenges as it works with partners to reach those who live in extreme and moderate poverty. Indeed, many of those who emerged from poverty in recent years remain vulnerable to shocks and slowdowns in growth. Concerted efforts to equalize opportunities are necessary for substantial improvements in shared prosperity.

Reaching the ambitious WBG twin goals will require high and sustained economic growth across the developing world that also translates more effectively into poverty reduction in each country. This kind of robust, sustainable, inclusive growth—that achieves the maximum possible increase in living standards of the less well-off—is not business as usual, and has important implications for the WBG. In particular, the quest for economic growth, poverty reduction and shared prosperity can no longer be seen as separate, nor can policy options be viewed as a trade-off between economic growth and poverty reduction. At the same time, these priorities must be consistent with each country’s economic, social and institutional context and challenges—there is no one-size-fits-all solution. Ultimately, the twin goals demand a sharper, country-specific understanding of the constraints to growth and the trade-offs that available macro and sectoral policy choices entail, to promote substantial improvements in the welfare of the less well-off.

The WBG’s first joint strategy seeks to position the institution to deliver better for its clients by: (1) maximizing development impact by identifying and tackling the most difficult development challenges; (2) promoting scaled-up partnerships strategically aligned with the goals; and (3) convening public and private resources, expertise and ideas.

To identify the most important areas for interventions to achieve the WBG’s twin goals, the WBG conducts a Systematic Country Diagnostic (SCD) preceding the preparation of its Country Partnership Frameworks (laying out the intervention areas for WBG programs). The SCD is an analytical product and in the case of South Africa, it will be prepared in collaboration with the National Planning Commission/Department of Monitoring and Evaluation in the Presidency. The relationship is governed by a Memorandum of Understanding.

As part of the relationship of the National Planning Commission, the World Bank team has committed to examining progress on the National Development Plan. To this end, it is important to understand the evolution of South Africa’s strategic policy direction since democracy in 1994, from the Reconstruction and Development Plan (RDP), Growth, Employment And Redistribution (GEAR), the Accelerated and Shared Growth Initiative South Africa (AsGISA), the New Growth Path (NGP) and the National Development Plan. One of the arguments for South African policy to be less effective than desired is that policy is articulated in a blurry way and is becoming increasingly fragmented—with instances of even competing objectives. This in itself can hamper progress on the twin goals given less effective policy. A consultant is to be hired to help with a quantitative analysis of the mentioned major South African policy documents.

Scope of the work covers application of natural language processing (NLP) to analyze RDP, GEAR, AsGISA, NGP, and National Development Plan. In addition, similar analysis is undertaken for National Budget Reviews from 1998 to 2017 to explore the evolution of emphasis on fiscal policy.

In relation to national development plans the aim is as follows: in the corpus of documents implement probabilistic topic modeling (Latent Dirichlet Allocation models) to identify core themes; estimate a range of models to identify optimal topic structure; visualize the results of topic modeling for interpretation using static graphics; identify semantic relationships between themes in the documents and map these topic correlations; identify key phrases across the documents in the corpus; and identify the relationship between structural factors and themes of the documents.

For the National Budget Reviews analysis: measure commitment to fiscal credibility and countercyclical fiscal policy by looking at frequency of the keywords and how it evolves over time. The dictionary of keywords identified as follows:

Using the dictionary of keywords the aim is to identify the context where these keywords appear in budgets and summarize the context as topics and trace evolution of topics over time.

Analysis of National Development Plans

Data

The texts of national development plans were downloaded from the following links:

New Growth Path collection consists of the following separate booklets that were used as separate documents:

The National Development Plan consists of fifteen chapters. As a single document it is 489 pages long, which is significantly more than any of the previous plans. Hence, for computational reasons, it was included in the analysis as separate chapters rather than one document. Overall, 24 documents were used in the analysis.

All the documents were converted into plain text files. Conversion from PDF to plain text led to multiple errors appearing due to some historical and no longer supported fonts compromising the conversion. Hence all the documents were spell-checked to capture most obvious typos.

Using R statistical software, plain text versions of national development plans were ingested and a “corpus” object for analysis was created (see https://en.wikipedia.org/wiki/Text_corpus for general introduction to the concept).

The table below provides summary information for our corpus.

We observe a dramatic increase in size of the plans over time. This is particularly true for NDP, which stands at 162,056 total words and 6,627 sentencces. Another way to look at the diversity of content in plans is focusing on types – distinct words. NDP has 32,965 types which is more than three times higher than the second largest number in NGP and almost twenty times higher than in AsgiSA. That may reflect more diverse issues that are being discussed in NDP.

The corpus was then transformed into separate words (tokens), accompanied by basic pre-processing:

  • removing punctuation;
  • removing symbols;
  • removing numbers;
  • removing twitter-related symbols;
  • removing embedded URLs;
  • removing hyphens.

Additionally, any digits and punctuation that may be part of tokens through mistakes in text conversion and input were also removed. Any tokens containing less than three characters long were removed as well. This picks up some additional mistakes and typos. Next all tokens were converted into lower case.

A document feature matrix (aka document term matrix) or DFM is a fundamental input into natural language processing (see https://en.wikipedia.org/wiki/Document-term_matrix). We construct a DFM from tokens after stemming and removing “stop words” (not carrying functional meaning) using the SMART list.

The DFM is trimmed by dropping tokens appearing less than three times, mainly to catch typos and text conversion mistakes. The logic is that if a token is used only once in all documents, that could be a feature that does not distinguish well between documents. Alternatively that can be a spelling mistake or typo. Total number of tokens (3135) shows the size of the trimmed DFM that we use in the analysis.

Frequency and keyness analysis

In our corpus as a whole, we can assess the most frequently occurring terms in our corpus, with the visualisation below focusing on the 20 most frequent words.

For convenience, the same information is presented as a traditional word cloud (with 100 most frequent terms).

We can also assess differences in frequency of word usage by development plans. This highlights the evolution of most frequently occurring terms (and thus saliency of the terms) over time.

RDP

Wordcloud plot of 100 most frequent terms in RDP:

We can explore which key terms appear in RDP more frequently than by chance using the concept of [keyness](https://en.wikipedia.org/wiki/Keyword_(linguistics). We calculate keyness for RDP compared to all other documents in our corpus (remaining development plans). The outputs are sorted in descending order by the association measure (chi2 here). Figure below visualises keyness between RDP and other development plans:

Terms on the right (in red) are words that appear significantly more frequently in RDP than would be expected by chance compared to all other national development plans. For example, “democrat”, “reconstruct”, “programm”, and “apartheid”. At the same time, the terms on the left (in blue) appear less frequently than in other documents: e.g., “growth”, “target”, “spatial”.

GEAR

In GEAR more prominent terms are around wages and employment, deficit, expenditure, and fiscal issues.

AsgiSA

AsgiSA most prominent terms are project acronyms pointing to more institution rather than policy focus.

NGP

NGP is introducing a set of commitments and references to green growth, and jobs.

NDP

NDP is interesting in that it has relatively fewer mentions of economic growth, employment, and real sector related terms. What sets NDP apart from previous development plans is its emphasis of health and low carbon economy, and corruption related issues.

Topic modeling

In the topic model analysis we consider the thematic structure of development plans and effect of structural variables. Given limited number of documents in this part of the analysis, we are only looking at thematic differences across documents as structural effects. That is whether themes change across development plans. In order to achieve that we implement a structural topic model (Roberts et al., 2016). We model topic prevalence in the context of the development plan covariate (a factor variable with a level for each individual plan). The aim is to statistically test whether the metadata affects the frequency with which a topic is discussed in development plans – the average proportion of a document discussing a topic.

Structural topic model or STM (Roberts et al., 2016) is a type of probabilistic topic models (Blei et al. 2003) that allows to assess the effect of covariates (see http://www.structuraltopicmodel.com; for an introduction and a nice overview of topic modeling see http://www.cs.columbia.edu/~blei/papers/Blei2012.pdf).

Searching for optimal number of topics

One key input into the topic modeling algorithm is specifying the number of topics the algorithm needs to uncover in the corpus. This can be done with a manual input, using human expert judgement to determine the number of topics. Alternatively, this can be done by focusing on semantic coherence (see Mimno et al., 2011) and exclusivity (see Bischof and Airoldi, 2012) measures. Highly frequent words in a given topic that don’t appear too often in other topics are said to make that topic exclusive. Cohesive and exclusive topics are more semantically useful.

We first generate a set of candidate models, here ranging between 3 and 30 topics. Then we plot exclusivity and semantic coherence estimates for each candidate model and choose the optimal number of topics as a balance between these two measures (see Roberts et al., 2016).

Plot below maps exclusivity and semantic coherence (numbers closer to zero indicate higher coherence), and select a model on the semantic coherence-exclusivity “frontier” (where no model strictly dominates another in terms of semantic coherence and exclusivity).

The model with nine topics is selected for our analysis (highlighted with vertical line). There’s a sharp drop in semantic coherence after \(k=9\).

Structural topic model with 9 topics

One way to summarize topics is to combine term frequency and exclusivity to that topic into a univariate summary statistic. In STM package in R this is implemented as FREX (see Bischof and Airoldi, 2012 and Airoldi and Bischof, 2016). The logic behind this measure is that both frequency and exclusivity are important factors in determining semantic content of a word and form a two dimensional summary of topical content. FREX is the geometric average of frequency and exclusivity and can be viewed as a univariate measure of topical importance.

STM authors suggest that nonexclusive words are less likely to carry topic-specific content, while infrequent words occur too rarely to form the semantic core of a topic. FREX is therefore combining information from the most frequent words in the corpus that are also likely to have been generated from the topic of interest to summarize its content.

The table below presents four types of word weightings using alternative measures. Highest probability words list the words within each topic with the highest probability. FREX are the words ranked by their frex measure discussed above. Lift is calculated by dividing the topic-word distribution by the empirical word count probability distribution. Sievert and Shirley (2014) point that the lift measure (Taddy 2011) aims to de-rank high-frequency terms, but in practice it often gives high ranking to very rare terms occurring in only a single topic. Score is a metric used in the lda R package by Jonathan Chang.

In practice, manual topic labeling is usually evaluated through a combination of the metrics below.

Topic 1 Top Words:
     Highest Prob: growth, employ, develop, south, path, job, economi, servic, econom, sector 
     FREX: driver, mine, path, growth, employ, framework, job, firm, creation, export 
     Lift: cwp, merger, spike, arbitr, buyer, curs, cushion, dfis, dst, edd 
     Score: speech, mine, export, dfis, edd, region, dismiss, nanc, diversifi, bee 
Topic 2 Top Words:
     Highest Prob: educ, school, develop, system, higher, nation, train, percent, qualiti, skill 
     FREX: school, teacher, scienc, teach, learner, educ, student, learn, knowledg, higher 
     Lift: postgradu, checklist, dropout, funza, interv, lushaka, phds, tongu, advisor, diploma 
     Score: teacher, mathemat, phd, learner, phds, certif, teach, percent, scienc, underperform 
Topic 3 Top Words:
     Highest Prob: health, social, south, system, care, servic, communiti, africa, percent, work 
     FREX: health, diseas, hiv, care, child, demograph, age, popul, insur, mortal 
     Lift: addict, conceptu, condom, gov, intersector, physician, pictur, rica, therapeut, antibiot 
     Score: mortal, matern, percent, age, health, nhi, death, hiv, hospit, insur 
Topic 4 Top Words:
     Highest Prob: train, skill, govern, develop, growth, busi, sector, commit, improv, programm 
     FREX: fet, artisan, traine, asgisa, skill, colleg, train, workplac, project, enrol 
     Lift: bpo, jipsa, recogn, umsobomvu, apprentic, asgisa, traine, fet, dead, eia 
     Score: fet, apprentic, asgisa, traine, jipsa, bpo, seta, dti, recogn, umsobomvu 
Topic 5 Top Words:
     Highest Prob: accord, commit, economi, local, green, youth, govern, busi, develop, procur 
     FREX: green, accord, procur, solar, constitu, localis, commit, youth, heat, instal 
     Lift: blsa, bought, cook, decemb, feder, hat, incandesc, jacket, mthalan, mxolisi 
     Score: accord, green, geyser, behalf, cop, heat, constitu, solar, localis, decemb 
Topic 6 Top Words:
     Highest Prob: develop, govern, programm, nation, rdp, communiti, south, polici, peopl, servic 
     FREX: rdp, democrat, reconstruct, hous, right, land, apartheid, legisl, rural, cultur 
     Lift: thoroughgo, abe, alli, amen, applianc, audio, captain, cbos, conglomer, councillor 
     Score: rdp, democrat, democratis, cent, reconstruct, media, right, parastat, peac, hostel 
Topic 7 Top Words:
     Highest Prob: south, africa, develop, econom, invest, polici, water, region, servic, transport 
     FREX: carbon, coal, mitig, spatial, ict, emiss, fuel, transport, gas, climat 
     Lift: angola, apport, augment, captiv, cleaner, combust, converg, crippl, des, desalin 
     Score: carbon, coal, region, refineri, reus, climat, emiss, mitig, corridor, bay 
Topic 8 Top Words:
     Highest Prob: public, servic, govern, municip, respons, depart, develop, polic, south, manag 
     FREX: corrupt, polic, recruit, municip, crime, safeti, justic, crimin, servant, soe 
     Lift: aptitud, blow, counterproduct, disagr, downgrad, freeli, lang, meritocrat, politician, prosecutor 
     Score: recruit, soe, whistl, polic, corrupt, servant, blower, deleg, junior, judici 
Topic 9 Top Words:
     Highest Prob: percent, growth, employ, increas, sector, rate, labour, market, year, polici 
     FREX: real, wage, exchang, deficit, fiscal, inflat, farmer, gdp, foreign, depreci 
     Lift: outward, spot, tenth, elast, semi, aggreg, agribusi, appendic, apr, aug 
     Score: page, percent, depreci, elast, exchang, dissav, macroeconom, assa, appendix, expenditur 

Manually assessing the word weightings across the four metrics above we can introduce the following labels:

  • Topic 1: Economic growth
  • Topic 2: Education
  • Topic 3: Health
  • Topic 4: Skills and training
  • Topic 5: Green economy
  • Topic 6: Reconstruction and democracy
  • Topic 7: Climate change and resources
  • Topic 8: Corruption and security
  • Topic 9: Fiscal policy and macroeconomy

This labeling is an outsider interpretation of the word weightings and will necessarily change with more domain expertise brought in to label the topics.

Figure below displays the topics ordered by their expected frequency across the corpus, with illustrative top FREX words.

Topical difference across programmes

In the STM framework we can estimate the effect of external covariates. As mentioned above, here external covariates are limited to differences across development programmes. This is due to the fact that it’s difficult to unambiguously attribute economic indicators like inflation or unemployment rates to documents that span several years in preparation and implementation.

Estimation is done with a linear regression where documents are the units, the outcome is the proportion of each document about a topic in an STM model and the covariate is the factor variable for national development programmes. Estimation incorporates measurement uncertainty from the STM model using the method of composition.

Plots below display the effect of our covariate on each estimated topic. The covariate is a nominal five-level factor variable for each development plan. We estimate mean topic proportions for each value of the covariate, with corresponding 95% confidence intervals of the effect.

Topics 1 (Economic growth) and 2 (Education) appear in all development programmes in similar proportions highlighting their stable importance over time.

Topic 3 (Health) is given higher of the NDP compared to other development programmes.

Topic 4 (Skills and training) is given higher attention in AsgiSA compared to other programmes, with the exception of NGP that is also, albeit statistically marginally, has larger coverage of the topic.

Topic 5 (Green economy) is given higher attention in NGP compared to other development programmes.

Topic 6 (Reconstruction and democracy) has a high coverage in RDP, as would be expected from the early national development plan.

Topics 7 (Climate change and resources) and 8 (Corruption and security) have higher coverage in the most recent national development programme (NDP).

Topic 9 (Fiscal policy and macroeconomy) has higher emphasis in the 1996 GEAR programme and, statistically marginally, in NDP compared to other development plans.

Topic modeling results highlight the issue of issue diversity mentioned ealrier. From nine topics identified NDP has a statistically significant, positive effect on four topics, while AsgiSA, GEAR, RDP have one statistically significant effect each and two for NGP.

Relationship between topics

We can assess the relationship between topics in the STM framework that allows correlations between topics. We calculate the correlation between estimates of the topic proportions and drop edges below the correlation threshold 0.01. Positive correlations between topics suggest that both topics are likely to be covered within a development programme.

Two sets of topics are connected with each other: Topics 1 and 9, and Topics 2 and 5. We can contrast the words across two connected topics by calculating the difference in probability of a word for the two topics, and normalizing the maximum difference in probability of any word between the two topics. These are often called perspective plots, where words are sized proportional to their use within the plotted topic combinations and oriented along the X-axis based on how much they favour each of the topics. The vertical configuration of the words is random.

Intuitively, topics related to economic growth (Topic 1) and fiscal policy and macroeconomy (Topic 9) are related. However, the perspective plot below relative emphases on different aspects across the topics. The words that straddle the probabilistic boundary between two topics relate to services and labour market. The words more central to individual topics highlight aspects of economic development policies.

Topics related to education (Topic 2) and green economy (Topic 5) are also more likely to be covered in the same development programme.

Topic shares per development plan

document topic Topic_Proportion
GEAR 1 0.0000000
AsgiSA 1 0.0000001
RDP 1 0.0000035
NGP 1 1.0016496
NDP 1 1.2122775
RDP 2 0.0000013
AsgiSA 2 0.0000163
GEAR 2 0.0000211
NGP 2 0.5375806
NDP 2 1.1439411
RDP 3 0.0000017
AsgiSA 3 0.0000241
GEAR 3 0.0001392
NGP 3 0.0162686
NDP 3 2.9091741
GEAR 4 0.0000000
RDP 4 0.0000048
NDP 4 0.0023302
AsgiSA 4 0.9999350
NGP 4 1.2227650
GEAR 5 0.0000000
AsgiSA 5 0.0000000
RDP 5 0.0000019
NDP 5 0.0000766
NGP 5 3.2209703
GEAR 6 0.0000000
AsgiSA 6 0.0000001
NGP 6 0.0001485
RDP 6 0.9999853
NDP 6 1.1076758
RDP 7 0.0000005
AsgiSA 7 0.0000076
NGP 7 0.0000242
GEAR 7 0.0000992
NDP 7 4.3094874
GEAR 8 0.0000000
RDP 8 0.0000002
AsgiSA 8 0.0000034
NGP 8 0.0004865
NDP 8 3.1038380
RDP 9 0.0000008
AsgiSA 9 0.0000133
NGP 9 0.0001067
GEAR 9 0.9997404
NDP 9 1.2111993

Each of the values in the table is an estimated proportion of words from that document that are generated from that topic. It is important to note that proportions do not add up to 1 per development plan. This is because, as mentioned earlier, we included NDP and NGP as individual chapters due to large text length imbalance, with estimates for individual chapters aggregated by development plan for presentation of the results. The numbers on in the table above should be treated as relative indicators of topic prevalence across documents.

The same informaiton is provided in the plots below (two variations different by the focus of presentation on topics vs development plans).

National Budget Review Analysis

Data

The data for this analysis comes from the National Budget Reviews. We downloaded all chapters (but not the appendices), and converted into plain text files with UTF8 encoding.

The table below provides summary information for our corpus.

We also pre-processed the corpus following the same steps as above. In addition we also removed “cent” and “billion” from the corpus as, in our setting, these were high frequency non-function words.

Overview of NBR corpus

Total number of tokens in NBR DFM is 4023. The most frequently occurring terms are shown below.

Visualised as a wordcloud:

Mapping out output stabilisation and credibility concepts

We assess two concepts: output stabilisation and credibility. Each concept is described by a list of keywords listed below that were provided by the World Bank:

  • output stabilisation: automatic stabilizers, tax buoyancy, countercyclical fiscal policy, cyclically adjusted budget balance, structural budget balance, exchange rate absorption, stimulus package, fiscal stimulus, bracket creep adjustment, rebates increase, expansionary fiscal policy, accommodating fiscal policy

  • credibility: sustainability, low risk, meeting targets, low volatility, sustainable fiscal path, low inflation, maximizing growth, strong multipliers

With the necessary adjustment for multiple usage and spelling used in NBR the dictionary of keywords used was as follows (a “*" character indicates a wild-card, i.e. versions of word endings):

Dictionary object with 2 key entries.
- [output_stabilisation]:
  - automatic stabiliser*, tax buoyancy, countercyclical fiscal polic*, cyclically adjusted budget balance*, structural budget balance*, exchange rate absorption, stimulus package*, fiscal stimul*, bracket creep adjustment*, rebate* increase*, expansionary fiscal polic*, accommodating fiscal polic*
- [credibility]:
  - sustainability, low risk*, meeting target*, low volatility, sustainable fiscal path, low inflation, maximis* growth, strong multiplier*

Frequency of both concepts appearing in NBR is presented in table below.

The same information is visualised in the plot below:

NBR exploratory analysis by year

1998

1999

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017

Linking development plans with NBRs

We can assess the linkage between development plans and NBRs by calculating similarities between documents. The simplest similarity measure between two documents that normalises the length of the documents during comparison is cosine similarity. First, we normalised the Document Feature Matrix using the TF-IDF (term frequency inverse document frequency) weights. The weight increases proportionally to the number of times a term appears in a document and offset by the frequency of the word in the corpus. It’s a standard weighting system in Information Retrieval and aims to capture that some words appear more frequently. Second, we view documents as a set of vectors in a vector space. The cosine of the angle between two vectors is a measure of their similarity. This is a standard measure in Information Retrieval. In these settings, cosine similarity ranges between 0 and 1, where 0 means that documents are orthogonal and 1 means the documents are the same.

The tables and plots below provide cosine similarity measures for each development plan and full set of National Budget Reviews.

RDP

  RDP.1994
NBR.1998 0.1927
NBR.2000 0.1291
NBR.2005 0.1279
NBR.2004 0.1264
NBR.2002 0.1135
NBR.2003 0.1057
NBR.2001 0.0968
NBR.2007 0.0964
NBR.2010 0.0943
NBR.1999 0.0933
NBR.2009 0.0837
NBR.2012 0.083
NBR.2006 0.0769
NBR.2014 0.0727
NBR.2008 0.0721
NBR.2017 0.0707
NBR.2011 0.0695
NBR.2013 0.0633
NBR.2015 0.0598
NBR.2016 0.058
  • scale_x_discrete(breaks=c(“0.5”,“1”,“2”), labels=c(“Dose 0.5”, “Dose 1”, “Dose 2”))

GEAR

  GEAR.1996
NBR.2006 0.1035
NBR.2004 0.1012
NBR.2010 0.1009
NBR.1998 0.0844
NBR.2000 0.0833
NBR.2003 0.0801
NBR.2002 0.0797
NBR.2007 0.0734
NBR.2005 0.0727
NBR.2001 0.0682
NBR.2008 0.0654
NBR.2015 0.0639
NBR.2016 0.0565
NBR.1999 0.0504
NBR.2009 0.0497
NBR.2014 0.0488
NBR.2013 0.0488
NBR.2012 0.0451
NBR.2011 0.0403
NBR.2017 0.0385

AsgiSA

  AsgiSA.2006
NBR.2001 0.0809
NBR.2002 0.0602
NBR.2008 0.0522
NBR.2007 0.0504
NBR.2016 0.0465
NBR.2009 0.042
NBR.2015 0.0417
NBR.2006 0.0393
NBR.1999 0.039
NBR.2010 0.0323
NBR.2005 0.0321
NBR.2000 0.0316
NBR.2003 0.0315
NBR.1998 0.0286
NBR.2017 0.0283
NBR.2013 0.0281
NBR.2014 0.0252
NBR.2004 0.0237
NBR.2011 0.0237
NBR.2012 0.0201

NGP

  NGP.2010
NBR.2017 0.1437
NBR.2003 0.1024
NBR.1998 0.0961
NBR.2001 0.0852
NBR.2014 0.0812
NBR.2000 0.0743
NBR.2005 0.0723
NBR.2013 0.0672
NBR.2006 0.0655
NBR.2015 0.0623
NBR.2010 0.0593
NBR.2004 0.0536
NBR.2011 0.0501
NBR.1999 0.0496
NBR.2002 0.0463
NBR.2009 0.0451
NBR.2016 0.043
NBR.2012 0.0427
NBR.2007 0.0398
NBR.2008 0.0382

NDP

  NDP.2012
NBR.2011 0.2032
NBR.2002 0.2009
NBR.2017 0.1925
NBR.2013 0.1732
NBR.2016 0.1677
NBR.2006 0.1526
NBR.2007 0.1512
NBR.2004 0.1464
NBR.2009 0.1459
NBR.2010 0.1404
NBR.2008 0.1387
NBR.2001 0.134
NBR.2014 0.1337
NBR.1999 0.1325
NBR.1998 0.1307
NBR.2015 0.129
NBR.2005 0.1258
NBR.2000 0.1244
NBR.2003 0.1127
NBR.2012 0.1092

References

LS0tCnRpdGxlOiAiU3VwcG9ydCB0byBTb3V0aCBBZnJpY2EgU3lzdGVtYXRpYyBDb3VudHJ5IERpYWdub3N0aWM6IFRoZSBkZXZlbG9wbWVudCBvZiBTb3V0aCBBZnJpY2FuIHBvbGljeSBwbGFubmluZyIKYXV0aG9yOgotIGFmZmlsaWF0aW9uOiBVbml2ZXJzaXR5IG9mIEVzc2V4LCBJbnN0aXR1dGUgZm9yIEFuYWx5dGljcyBhbmQgRGF0YSBTY2llbmNlCiAgZW1haWw6IHMubWlraGF5bG92QGVzc2V4LmFjLnVrCiAgbmFtZTogU2xhdmEgTWlraGF5bG92LCBQcm9mZXNzb3Igb2YgUHVibGljIFBvbGljeSBhbmQgRGF0YSBTY2llbmNlCmRhdGU6IDExIERlY2VtYmVyIDIwMTcKb3V0cHV0OgogIHdvcmRfZG9jdW1lbnQ6IAogICAgdG9jOiB5ZXMKICBodG1sX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCi0tLQoKIyBFeGVjdXRpdmUgU3VtbWFyeQpUaGUgZXZvbHV0aW9uIG9mIFNvdXRoIEFmcmljYSdzIHN0cmF0ZWdpYyBwb2xpY3kgZGlyZWN0aW9ucyB3YXMgYW5hbHlzZWQgdGhyb3VnaCB0aGUgYXBwbGljYXRpb24gb2YgbmF0dXJhbCBsYW5ndWFnZSBwcm9jZXNzaW5nIChOTFApIHRlY2huaXF1ZXMgdG8gdGhlIHRleHRzIG9mIHRoZSBSZWNvbnN0cnVjdGlvbiBhbmQgRGV2ZWxvcG1lbnQgUGxhbiAoUkRQKSwgR3Jvd3RoLCBFbXBsb3ltZW50IEFuZCBSZWRpc3RyaWJ1dGlvbiAoR0VBUiksIHRoZSBBY2NlbGVyYXRlZCBhbmQgU2hhcmVkIEdyb3d0aCBJbml0aWF0aXZlIFNvdXRoIEFmcmljYSAoQXNnaVNBKSwgdGhlIE5ldyBHcm93dGggUGF0aCAoTkdQKSwgYW5kIHRoZSBOYXRpb25hbCBEZXZlbG9wbWVudCBQbGFuIChORFApLiAKCkFsbCBkb2N1bWVudHMgZW1waGFzaXNlIHRoZSByb2xlIG9mIGdvdmVybmFuY2UgYW5kIHB1YmxpYyBzZWN0b3IgZm9yIGVjb25vbWljIGRldmVsb3BtZW50LiBSRFAgaXMgZW1waGFzaXNpbmcgdGhlIHRlcm1zIHJlbGF0ZWQgdG8gZGVtb2NyYXRpc2F0aW9uIGFuZCByZWNvbnN0cnVjdGlvbiwgd2l0aCBsZXNzIGltcG9ydGFuY2Ugc2hvd24gdG8gaXNzdWVzIHJlbGF0ZWQgdG8gZWNvbm9taWMgZ3Jvd3RoLiBUaGlzIGNoYW5nZXMgaW4gR0VBUiB3aGVyZSBpc3N1ZXMgb2YgZmlzY2FsIHBvbGljeSBhbmQgc3RhYmlsaXR5LCB0b2dldGhlciB3aXRoIGVtcGxveW1lbnQgcmVsYXRlZCBpc3N1ZXMsIGNvbWUgdG8gdGhlIGZvcmUuIEFzZ2lTQSBicmluZ3MgdXAgdGVybXMgcmVsYXRlZCB0byBwcm9qZWN0cyBhbmQgaW5zdGl0dXRpb25zIHdpdGggYWRkaXRpb25hbCBlbXBoYXNpcyBvbiBhZ3JpY3VsdHVyZS4gTkdQIGlzIG1vcmUgY2VudHJhbGx5IGNvbmNlcm5lZCB3aXRoIGVjb25vbWljIGdyb3d0aCwgYXNwZWN0cyBvZiBncmVlbiBlY29ub215LCBhbmQgZW1wbG95bWVudCBpc3N1ZXMsIHBhcnRpY3VsYXJseSBhbW9uZyB5b3V0aHMuIFRoZSBtb3N0IHJlY2VudCBORFAgaXMgaW50ZXJlc3RpbmcgaW4gdGhhdCBpdCBoYXMgcmVsYXRpdmVseSBmZXdlciBtZW50aW9ucyBvZiBlY29ub21pYyBncm93dGgsIGVtcGxveW1lbnQsIGFuZCByZWFsIHNlY3RvciByZWxhdGVkIHRlcm1zLiBXaGF0IHNldHMgTkRQIGFwYXJ0IGZyb20gcHJldmlvdXMgZGV2ZWxvcG1lbnQgcGxhbnMgaXMgaXRzIGVtcGhhc2lzIG9mIGhlYWx0aCBhbmQgbG93IGNhcmJvbiBlY29ub215LCBhbmQgY29ycnVwdGlvbiByZWxhdGVkIGlzc3Vlcy4gCgpJbiBzdGF0aXN0aWNhbCwgcHJvYmFiaWxpc3RpYyB0b3BpYyBtb2RlbGluZyBhbmFseXNpcywgbmluZSB0b3BpY3MgYXJlIGlkZW50aWZpZWQgYWNyb3NzIGFsbCBkZXZlbG9wbWVudCBwbGFucy4gSW4gdGhlIGRlY3JlYXNpbmcgb3JkZXIgb2YgcHJvcG9ydGlvbiBvZiBkZXZlbG9wbWVudCBwbGFucycgZG9jdW1lbnRzLCB0aGUgdG9waWNzIHJlbGF0ZSB0bzogY2xpbWF0ZSBjaGFuZ2UgYW5kIHJlc291cmNlczsgZ3JlZW4gZWNvbm9teTsgY29ycnVwdGlvbiBhbmQgc2VjdXJpdHk7IGhlYWx0aDsgc2tpbGxzIGFuZCB0cmFpbmluZzsgZWNvbm9taWMgZ3Jvd3RoOyBmaXNjYWwgcG9saWN5IGFuZCBtYWNyb2Vjb25vbXk7IHJlY29uc3RydWN0aW9uIGFuZCBkZW1vY3JhY3k7IGFuZCBlZHVjYXRpb24uIFN1cHBvcnRpbmcgZXhwbG9yYXRvcnkgc3R1ZHkgcmVzdWx0cywgcHJvYmFiaWxpc3RpYyB0b3BpYyBtb2RlbGluZyBhbmFseXNpcyBzdWdnZXN0cyB0aGF0IGhlYWx0aCwgY2xpbWF0ZSBjaGFuZ2UgYW5kIHJlc291cmNlcywgYW5kIGNvcnJ1cHRpb24gYW5kIHNlY3VyaXR5IGFyZSBtb3JlIHByb21pbmVudCBpbiBORFAgY29tcGFyZWQgdG8gb3RoZXIgZGV2ZWxvcG1lbnQgcGxhbnMuIFNraWxscyBhbmQgdHJhaW5pbmcgaXMgY292ZXJlZCBtb3JlIGluIEFzZ2lTQSBhbmQgbWFyZ2luYWxseSBzbyBpbiBOR1AsIGNvbXBhcmVkIHRvIG90aGVyIGRldmVsb3BtZW50IHBsYW5zLiBOR1AgYWxzbyBnaXZlcyBtb3JlIHByb21pbmVuY2UgdG8gZ3JlZW4gZWNvbm9teSB0b3BpYyBjb21wYXJlZCB0byBvdGhlciBkZXZlbG9wbWVudCBwbGFucy4gRmlzY2FsIHBvbGljeSBhbmQgbWFjcm9lY29ub215IGhhcyBoaWdoZXIgY292ZXJhZ2UgaW4gR0VBUi4gQW5kLCBhcyBleHBlY3RlZCwgcmVjb25zdHJ1Y3Rpb24gYW5kIGRlbW9jcmFjeSBhcmUgbW9yZSBjb3ZlcmVkIGluIFJEUC4gQW5hbHlzaXMgb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRvcGljcyBzdWdnZXN0cyB0aGF0IHRvcGljcyByZWxhdGVkIHRvIGVkdWNhdGlvbiBhbmQgZ3JlZW4gZWNvbm9teSBhcmUgbW9yZSBsaWtlbHkgdG8gYmUgY292ZXJlZCBpbiB0aGUgc2FtZSBkb2N1bWVudC4gU2ltaWxhcmx5LCBlY29ub21pYyBncm93dGggYW5kIGZpc2NhbCBwb2xpY3kgYW5kIG1hY3JvZWNvbm9teSB0b3BpY3MgYXBwZWFyIGluIHRoZSBzYW1lIGRldmVsb3BtZW50IHBsYW5zLgoKT25lIGltcG9ydGFudCBpc3N1ZSBpcyB0aGUgZGl2ZXJzaXR5IG9mIGNvbnRlbnQgaW4gZGV2ZWxvcG1lbnQgcGxhbnMgb3ZlciB0aW1lLiBXZSBvYnNlcnZlIGEgZHJhbWF0aWMgaW5jcmVhc2UgaW4gc2l6ZSBvZiB0aGUgcGxhbnMgb3ZlciB0aW1lLiBUaGlzIGlzIHBhcnRpY3VsYXJseSB0cnVlIGZvciBORFAsIHdoaWNoIHN0YW5kcyBhdCAxNjIsMDU2IHRvdGFsIHdvcmRzIGFuZCA2LDYyNyBzZW50ZW5jY2VzLiBUaGUgbnVtYmVyIG9mIGRpc3RpbmN0IHdvcmRzIGluIE5EUCBpcyAzMiw5NjUuIFRoaXMgaXMgbW9yZSB0aGFuIHRocmVlIHRpbWVzIGhpZ2hlciB0aGFuIHRoZSBzZWNvbmQgbGFyZ2VzdCBudW1iZXIgaW4gTkdQIGFuZCBhbG1vc3QgdHdlbnR5IHRpbWVzIGhpZ2hlciB0aGFuIGluIEFzZ2lTQS4gVGhhdCBtYXkgcmVmbGVjdCBtb3JlIGRpdmVyc2UgaXNzdWVzIHRoYXQgYXJlIGJlaW5nIGRpc2N1c3NlZCBpbiBORFAuIFRvcGljIG1vZGVsaW5nIHJlc3VsdHMgaGlnaGxpZ2h0IHRoZSBzYW1lIGlzc3VlLiBGcm9tIG5pbmUgdG9waWNzIGlkZW50aWZpZWQgTkRQIGhhcyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHBvc2l0aXZlIGVmZmVjdCBvbiBmb3VyIHRvcGljcywgd2hpbGUgQXNnaVNBLCBHRUFSLCBSRFAgaGF2ZSBvbmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBlZmZlY3QgZWFjaCBhbmQgdHdvIGZvciBOR1AuCgpFbXBsb3ltZW50IGFuZCBqb2JzIGFyZSBwcm9taW5lbnQgaW4gdGhlIGRldmVsb3BtZW50IHBsYW5zLiBGcm9tIHByb2JhYmlsaXN0aWMgdG9waWMgbW9kZWxpbmcgd2UgaWRlbnRpZmllZCBvbmUgdG9waWMgKG91dCBvZiBuaW5lKSBmb2N1c2luZyBvbiBpc3N1ZXMgb2Ygam9icyBhbmQgZW1wbG95bWVudC4gTW9yZSBnZW5lcmFsbHksIGVtcGxveW1lbnQgcmVsYXRlZCB0ZXJtIGlzIHRoZSA4dGggbW9zdCBmcmVxdWVudCB3b3JkIGluIHRoZSB3aG9sZSBjb3JwdXMuIFRvcCA1MCB3b3JkcyBhbHNvIGNvbnRhaW4gcmVmZXJlbmNlcyB0byB3b3JrLCBqb2JzLCBhbmQgbGFib3VyLiAgCgpJbiB0aGUgYW5hbHlzaXMgb2YgTmF0aW9uYWwgQnVkZ2V0IFJldmlld3Mgd2UgZm9jdXNlZCBvbiB0d28gY29uY2VwdHMgKG91dHB1dCBzdGFiaWxpc2F0aW9uIGFuZCBjcmVkaWJpbGl0eSksIGRlZmluZWQgdGhyb3VnaCBhIHNldCBvZiBrZXl3b3JkcyBwcm92aWRlZCBieSB0aGUgV29ybGQgQmFuay4gVG90YWwgbWVudGlvbnMgb2YgYm90aCBjb25jZXB0cyBpbiBOQlIgY29ycHVzIHdhcyB0cmFjZWQgc2luY2UgMTk5OCB1bnRpbCAyMDE3LiAiT3V0cHV0IHN0YWJpbGlzYXRpb24iIHBlYWtlZCBpbiB0aGUgMjAwOSBOQlIsIHdoaWxlICJjcmVkaWJpbGl0eSIgcmVhY2hlZCBpdHMgcGVhayBpbiAyMDEzLiBBbHRob3VnaCAiY3JlZGliaWxpdHkiIHdhcyBnZW5lcmFsbHkgbW9yZSBvZnRlbiBtZW50aW9uZWQgaW4gTkJSIG92ZXIgdGltZSwgdGhlcmUgaGFzIGJlZW4gYW4gdXBzd2luZyBpbiBtZW50aW9ucyBvZiAib3V0cHV0IHN0YWJpbGlzYXRpb24iIHNpbmNlIDIwMTYgYW5kIG92ZXJ0YWtpbmcgImNyZWRpYmlsaXR5IiBpbiB0aGUgMjAxNyBOQlIuIAoKIyBPdmVydmlldyBvZiB0aGUgcHJvamVjdAoKVGhlIFdvcmxkIEJhbmsgR3JvdXAgKFdCRykgdHdpbiBnb2FscyBvZiBlbmRpbmcgZXh0cmVtZSBwb3ZlcnR5IGFuZCBwcm9tb3Rpbmcgc2hhcmVkIHByb3NwZXJpdHkgcmVmbGVjdCBhIG5ldyBnbG9iYWwgbGFuZHNjYXBlOiBvbmUgaW4gd2hpY2ggZGV2ZWxvcGluZyBjb3VudHJpZXMgaGF2ZSBhbiB1bnByZWNlZGVudGVkIG9wcG9ydHVuaXR5IHRvIGVuZCBleHRyZW1lIHBvdmVydHkgd2l0aGluIGEgZ2VuZXJhdGlvbi4gVGhlIFdCRyB3aWxsIGZhY2UgdHJhZGl0aW9uYWwgYW5kIG5ldyBjaGFsbGVuZ2VzIGFzIGl0IHdvcmtzIHdpdGggcGFydG5lcnMgdG8gcmVhY2ggdGhvc2Ugd2hvIGxpdmUgaW4gZXh0cmVtZSBhbmQgbW9kZXJhdGUgcG92ZXJ0eS4gSW5kZWVkLCBtYW55IG9mIHRob3NlIHdobyBlbWVyZ2VkIGZyb20gcG92ZXJ0eSBpbiByZWNlbnQgeWVhcnMgcmVtYWluIHZ1bG5lcmFibGUgdG8gc2hvY2tzIGFuZCBzbG93ZG93bnMgaW4gZ3Jvd3RoLiBDb25jZXJ0ZWQgZWZmb3J0cyB0byBlcXVhbGl6ZSBvcHBvcnR1bml0aWVzIGFyZSBuZWNlc3NhcnkgZm9yIHN1YnN0YW50aWFsIGltcHJvdmVtZW50cyBpbiBzaGFyZWQgcHJvc3Blcml0eS4gCgpSZWFjaGluZyB0aGUgYW1iaXRpb3VzIFdCRyB0d2luIGdvYWxzIHdpbGwgcmVxdWlyZSBoaWdoIGFuZCBzdXN0YWluZWQgZWNvbm9taWMgZ3Jvd3RoIGFjcm9zcyB0aGUgZGV2ZWxvcGluZyB3b3JsZCB0aGF0IGFsc28gdHJhbnNsYXRlcyBtb3JlIGVmZmVjdGl2ZWx5IGludG8gcG92ZXJ0eSByZWR1Y3Rpb24gaW4gZWFjaCBjb3VudHJ5LiBUaGlzIGtpbmQgb2Ygcm9idXN0LCBzdXN0YWluYWJsZSwgaW5jbHVzaXZlIGdyb3d0aOKAlHRoYXQgYWNoaWV2ZXMgdGhlIG1heGltdW0gcG9zc2libGUgaW5jcmVhc2UgaW4gbGl2aW5nIHN0YW5kYXJkcyBvZiB0aGUgbGVzcyB3ZWxsLW9mZuKAlGlzIG5vdCBidXNpbmVzcyBhcyB1c3VhbCwgYW5kIGhhcyBpbXBvcnRhbnQgaW1wbGljYXRpb25zIGZvciB0aGUgV0JHLiBJbiBwYXJ0aWN1bGFyLCB0aGUgcXVlc3QgZm9yIGVjb25vbWljIGdyb3d0aCwgcG92ZXJ0eSByZWR1Y3Rpb24gYW5kIHNoYXJlZCBwcm9zcGVyaXR5IGNhbiBubyBsb25nZXIgYmUgc2VlbiBhcyBzZXBhcmF0ZSwgbm9yIGNhbiBwb2xpY3kgb3B0aW9ucyBiZSB2aWV3ZWQgYXMgYSB0cmFkZS1vZmYgYmV0d2VlbiBlY29ub21pYyBncm93dGggYW5kIHBvdmVydHkgcmVkdWN0aW9uLiBBdCB0aGUgc2FtZSB0aW1lLCB0aGVzZSBwcmlvcml0aWVzIG11c3QgYmUgY29uc2lzdGVudCB3aXRoIGVhY2ggY291bnRyeeKAmXMgZWNvbm9taWMsIHNvY2lhbCBhbmQgaW5zdGl0dXRpb25hbCBjb250ZXh0IGFuZCBjaGFsbGVuZ2Vz4oCUdGhlcmUgaXMgbm8gb25lLXNpemUtZml0cy1hbGwgc29sdXRpb24uIFVsdGltYXRlbHksIHRoZSB0d2luIGdvYWxzIGRlbWFuZCBhIHNoYXJwZXIsIGNvdW50cnktc3BlY2lmaWMgdW5kZXJzdGFuZGluZyBvZiB0aGUgY29uc3RyYWludHMgdG8gZ3Jvd3RoIGFuZCB0aGUgdHJhZGUtb2ZmcyB0aGF0IGF2YWlsYWJsZSBtYWNybyBhbmQgc2VjdG9yYWwgcG9saWN5IGNob2ljZXMgZW50YWlsLCB0byBwcm9tb3RlIHN1YnN0YW50aWFsIGltcHJvdmVtZW50cyBpbiB0aGUgd2VsZmFyZSBvZiB0aGUgbGVzcyB3ZWxsLW9mZi4gCgpUaGUgV0JH4oCZcyBmaXJzdCBqb2ludCBzdHJhdGVneSBzZWVrcyB0byBwb3NpdGlvbiB0aGUgaW5zdGl0dXRpb24gdG8gZGVsaXZlciBiZXR0ZXIgZm9yIGl0cyBjbGllbnRzIGJ5OiAoMSkgbWF4aW1pemluZyBkZXZlbG9wbWVudCBpbXBhY3QgYnkgaWRlbnRpZnlpbmcgYW5kIHRhY2tsaW5nIHRoZSBtb3N0IGRpZmZpY3VsdCBkZXZlbG9wbWVudCBjaGFsbGVuZ2VzOyAoMikgcHJvbW90aW5nIHNjYWxlZC11cCBwYXJ0bmVyc2hpcHMgc3RyYXRlZ2ljYWxseSBhbGlnbmVkIHdpdGggdGhlIGdvYWxzOyBhbmQgKDMpIGNvbnZlbmluZyBwdWJsaWMgYW5kIHByaXZhdGUgcmVzb3VyY2VzLCBleHBlcnRpc2UgYW5kIGlkZWFzLgoKVG8gaWRlbnRpZnkgdGhlIG1vc3QgaW1wb3J0YW50IGFyZWFzIGZvciBpbnRlcnZlbnRpb25zIHRvIGFjaGlldmUgdGhlIFdCR+KAmXMgdHdpbiBnb2FscywgdGhlIFdCRyBjb25kdWN0cyBhIFN5c3RlbWF0aWMgQ291bnRyeSBEaWFnbm9zdGljIChTQ0QpIHByZWNlZGluZyB0aGUgcHJlcGFyYXRpb24gb2YgaXRzIENvdW50cnkgUGFydG5lcnNoaXAgRnJhbWV3b3JrcyAobGF5aW5nIG91dCB0aGUgaW50ZXJ2ZW50aW9uIGFyZWFzIGZvciBXQkcgcHJvZ3JhbXMpLiBUaGUgU0NEIGlzIGFuIGFuYWx5dGljYWwgcHJvZHVjdCBhbmQgaW4gdGhlIGNhc2Ugb2YgU291dGggQWZyaWNhLCBpdCB3aWxsIGJlIHByZXBhcmVkIGluIGNvbGxhYm9yYXRpb24gd2l0aCB0aGUgTmF0aW9uYWwgUGxhbm5pbmcgQ29tbWlzc2lvbi9EZXBhcnRtZW50IG9mIE1vbml0b3JpbmcgYW5kIEV2YWx1YXRpb24gaW4gdGhlIFByZXNpZGVuY3kuIFRoZSByZWxhdGlvbnNoaXAgaXMgZ292ZXJuZWQgYnkgYSBNZW1vcmFuZHVtIG9mIFVuZGVyc3RhbmRpbmcuIAoKQXMgcGFydCBvZiB0aGUgcmVsYXRpb25zaGlwIG9mIHRoZSBOYXRpb25hbCBQbGFubmluZyBDb21taXNzaW9uLCB0aGUgV29ybGQgQmFuayB0ZWFtIGhhcyBjb21taXR0ZWQgdG8gZXhhbWluaW5nIHByb2dyZXNzIG9uIHRoZSBOYXRpb25hbCBEZXZlbG9wbWVudCBQbGFuLiBUbyB0aGlzIGVuZCwgaXQgaXMgaW1wb3J0YW50IHRvIHVuZGVyc3RhbmQgdGhlIGV2b2x1dGlvbiBvZiBTb3V0aCBBZnJpY2HigJlzIHN0cmF0ZWdpYyBwb2xpY3kgZGlyZWN0aW9uIHNpbmNlIGRlbW9jcmFjeSBpbiAxOTk0LCBmcm9tIHRoZSBSZWNvbnN0cnVjdGlvbiBhbmQgRGV2ZWxvcG1lbnQgUGxhbiAoUkRQKSwgR3Jvd3RoLCBFbXBsb3ltZW50IEFuZCBSZWRpc3RyaWJ1dGlvbiAoR0VBUiksIHRoZSBBY2NlbGVyYXRlZCBhbmQgU2hhcmVkIEdyb3d0aCBJbml0aWF0aXZlIFNvdXRoIEFmcmljYSAoQXNHSVNBKSwgdGhlIE5ldyBHcm93dGggUGF0aCAoTkdQKSBhbmQgdGhlIE5hdGlvbmFsIERldmVsb3BtZW50IFBsYW4uIE9uZSBvZiB0aGUgYXJndW1lbnRzIGZvciBTb3V0aCBBZnJpY2FuIHBvbGljeSB0byBiZSBsZXNzIGVmZmVjdGl2ZSB0aGFuIGRlc2lyZWQgaXMgdGhhdCBwb2xpY3kgaXMgYXJ0aWN1bGF0ZWQgaW4gYSBibHVycnkgd2F5IGFuZCBpcyBiZWNvbWluZyBpbmNyZWFzaW5nbHkgZnJhZ21lbnRlZOKAlHdpdGggaW5zdGFuY2VzIG9mIGV2ZW4gY29tcGV0aW5nIG9iamVjdGl2ZXMuIFRoaXMgaW4gaXRzZWxmIGNhbiBoYW1wZXIgcHJvZ3Jlc3Mgb24gdGhlIHR3aW4gZ29hbHMgZ2l2ZW4gbGVzcyBlZmZlY3RpdmUgcG9saWN5LiBBIGNvbnN1bHRhbnQgaXMgdG8gYmUgaGlyZWQgdG8gaGVscCB3aXRoIGEgcXVhbnRpdGF0aXZlIGFuYWx5c2lzIG9mIHRoZSBtZW50aW9uZWQgbWFqb3IgU291dGggQWZyaWNhbiBwb2xpY3kgZG9jdW1lbnRzLgoKU2NvcGUgb2YgdGhlIHdvcmsgY292ZXJzIGFwcGxpY2F0aW9uIG9mIG5hdHVyYWwgbGFuZ3VhZ2UgcHJvY2Vzc2luZyAoTkxQKSB0byBhbmFseXplIFJEUCwgR0VBUiwgQXNHSVNBLCBOR1AsIGFuZCBOYXRpb25hbCBEZXZlbG9wbWVudCBQbGFuLiBJbiBhZGRpdGlvbiwgc2ltaWxhciBhbmFseXNpcyBpcyB1bmRlcnRha2VuIGZvciBOYXRpb25hbCBCdWRnZXQgUmV2aWV3cyBmcm9tIDE5OTggdG8gMjAxNyB0byBleHBsb3JlIHRoZSBldm9sdXRpb24gb2YgZW1waGFzaXMgb24gZmlzY2FsIHBvbGljeS4gCgpJbiByZWxhdGlvbiB0byBuYXRpb25hbCBkZXZlbG9wbWVudCBwbGFucyB0aGUgYWltIGlzIGFzIGZvbGxvd3M6IGluIHRoZSBjb3JwdXMgb2YgZG9jdW1lbnRzIGltcGxlbWVudCBwcm9iYWJpbGlzdGljIHRvcGljIG1vZGVsaW5nIChMYXRlbnQgRGlyaWNobGV0IEFsbG9jYXRpb24gbW9kZWxzKSB0byBpZGVudGlmeSBjb3JlIHRoZW1lczsgZXN0aW1hdGUgYSByYW5nZSBvZiBtb2RlbHMgdG8gaWRlbnRpZnkgb3B0aW1hbCB0b3BpYyBzdHJ1Y3R1cmU7IHZpc3VhbGl6ZSB0aGUgcmVzdWx0cyBvZiB0b3BpYyBtb2RlbGluZyBmb3IgaW50ZXJwcmV0YXRpb24gdXNpbmcgc3RhdGljIGdyYXBoaWNzOyBpZGVudGlmeSBzZW1hbnRpYyByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlbWVzIGluIHRoZSBkb2N1bWVudHMgYW5kIG1hcCB0aGVzZSB0b3BpYyBjb3JyZWxhdGlvbnM7IGlkZW50aWZ5IGtleSBwaHJhc2VzIGFjcm9zcyB0aGUgZG9jdW1lbnRzIGluIHRoZSBjb3JwdXM7IGFuZCBpZGVudGlmeSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gc3RydWN0dXJhbCBmYWN0b3JzIGFuZCB0aGVtZXMgb2YgdGhlIGRvY3VtZW50cy4gCgpGb3IgdGhlIE5hdGlvbmFsIEJ1ZGdldCBSZXZpZXdzIGFuYWx5c2lzOiBtZWFzdXJlIGNvbW1pdG1lbnQgdG8gZmlzY2FsIGNyZWRpYmlsaXR5IGFuZCBjb3VudGVyY3ljbGljYWwgZmlzY2FsIHBvbGljeSBieSBsb29raW5nIGF0IGZyZXF1ZW5jeSBvZiB0aGUga2V5d29yZHMgYW5kIGhvdyBpdCBldm9sdmVzIG92ZXIgdGltZS4gVGhlIGRpY3Rpb25hcnkgb2Yga2V5d29yZHMgaWRlbnRpZmllZCBhcyBmb2xsb3dzOgoKLSBfb3V0cHV0IHN0YWJpbGlzYXRpb25fOiBhdXRvbWF0aWMgc3RhYmlsaXNlcnMsIHRheCBidW95YW5jeSwgY291bnRlcmN5Y2xpY2FsIGZpc2NhbCBwb2xpY3ksIGN5Y2xpY2FsbHkgYWRqdXN0ZWQgYnVkZ2V0IGJhbGFuY2UsIHN0cnVjdHVyYWwgYnVkZ2V0IGJhbGFuY2UsIGV4Y2hhbmdlIHJhdGUgYWJzb3JwdGlvbiwgc3RpbXVsdXMgcGFja2FnZSwgZmlzY2FsIHN0aW11bHVzLCBicmFja2V0IGNyZWVwIGFkanVzdG1lbnQsIHJlYmF0ZXMgaW5jcmVhc2UsIGV4cGFuc2lvbmFyeSBmaXNjYWwgcG9saWN5LCBhY2NvbW1vZGF0aW5nIGZpc2NhbCBwb2xpY3kKCi0gX2NyZWRpYmlsaXR5XzogU3VzdGFpbmFiaWxpdHksIGxvdyByaXNrLCBtZWV0aW5nIHRhcmdldHMsIGxvdyB2b2xhdGlsaXR5LCBzdXN0YWluYWJsZSBmaXNjYWwgcGF0aCwgbG93IGluZmxhdGlvbiwgbWF4aW1pc2luZyBncm93dGgsIHN0cm9uZyBtdWx0aXBsaWVycwoKVXNpbmcgdGhlIGRpY3Rpb25hcnkgb2Yga2V5d29yZHMgdGhlIGFpbSBpcyB0byBpZGVudGlmeSB0aGUgY29udGV4dCB3aGVyZSB0aGVzZSBrZXl3b3JkcyBhcHBlYXIgaW4gYnVkZ2V0cyBhbmQgc3VtbWFyaXplIHRoZSBjb250ZXh0IGFzIHRvcGljcyBhbmQgdHJhY2UgZXZvbHV0aW9uIG9mIHRvcGljcyBvdmVyIHRpbWUuCgojIEFuYWx5c2lzIG9mIE5hdGlvbmFsIERldmVsb3BtZW50IFBsYW5zCgojIyBEYXRhCgpUaGUgdGV4dHMgb2YgbmF0aW9uYWwgZGV2ZWxvcG1lbnQgcGxhbnMgd2VyZSBkb3dubG9hZGVkIGZyb20gdGhlIGZvbGxvd2luZyBsaW5rczoKCi0gW1JlY29uc3RydWN0aW9uIGFuZCBEZXZlbG9wbWVudCBQcm9ncmFtbWVdKGh0dHBzOi8vd3d3Lm5lbHNvbm1hbmRlbGEub3JnL29tYWxsZXkvaW5kZXgucGhwL3NpdGUvcS8wM2x2MDIwMzkvMDRsdjAyMTAzLzA1bHYwMjEyMC8wNmx2MDIxMjYuaHRtKQotIFtHcm93dGgsIEVtcGxveW1lbnQgYW5kIFJlZGlzdHJpYnV0aW9uXShodHRwczovL3d3dy5uZWxzb25tYW5kZWxhLm9yZy9vbWFsbGV5L2Npcy9vbWFsbGV5L09NYWxsZXlXZWIvZGF0L0dFQVIucGRmKQotIFtBY2NlbGVyYXRlZCBhbmQgU2hhcmVkIEdyb3d0aCBJbml0aWF0aXZlXShodHRwczovL3d3dy5uZWxzb25tYW5kZWxhLm9yZy9vbWFsbGV5L2luZGV4LnBocC9zaXRlL3EvMDNsdjAyNDA5LzA0bHYwMjQxMC8wNWx2MDI0MTUvMDZsdjAyNDE2Lmh0bSkKLSBbTmV3IEdyb3d0aCBQYXRoXShodHRwOi8vd3d3LmVjb25vbWljLmdvdi56YS9jb21tdW5pY2F0aW9ucy9wdWJsaWNhdGlvbnMvbmV3LWdyb3d0aC1wYXRoLXNlcmllcykKLSBbTmF0aW9uYWwgRGV2ZWxvcG1lbnQgUGxhbl0oaHR0cDovL3d3dy5uYXRpb25hbHBsYW5uaW5nY29tbWlzc2lvbi5vcmcuemEvUGFnZXMvTkRQLmFzcHgpCgpOZXcgR3Jvd3RoIFBhdGggY29sbGVjdGlvbiBjb25zaXN0cyBvZiB0aGUgZm9sbG93aW5nIHNlcGFyYXRlIGJvb2tsZXRzIHRoYXQgd2VyZSB1c2VkIGFzIHNlcGFyYXRlIGRvY3VtZW50czoKCi0gW05ldyBHcm93dGggUGF0aCAoTkdQKSBCb29rbGV0IDE6IEZyYW1ld29ya10oaHR0cDovL3d3dy5lY29ub21pYy5nb3YuemEvY29tbXVuaWNhdGlvbnMvcHVibGljYXRpb25zL25ldy1ncm93dGgtcGF0aC1zZXJpZXMpCi0gW0FjY29yZCAxOiBOYXRpb25hbCBTa2lsbHMgQWNjb3JkXShodHRwOi8vd3d3LmVjb25vbWljLmdvdi56YS9jb21tdW5pY2F0aW9ucy9wdWJsaWNhdGlvbnMvbmF0aW9uYWwtc2tpbGxzLWFjY29yZCkKLSBbQWNjb3JkIDI6IEJhc2ljIEVkdWNhdGlvbiBBY2NvcmRdKGh0dHA6Ly93d3cuZWNvbm9taWMuZ292LnphL2NvbW11bmljYXRpb25zL3B1YmxpY2F0aW9ucy9iYXNpYy1lZHVjYXRpb24tYWNjb3JkKQotIFtBY2NvcmQgMzogTG9jYWwgUHJvY3VyZW1lbnQgQWNjb3JkXShodHRwOi8vd3d3LmVjb25vbWljLmdvdi56YS9jb21tdW5pY2F0aW9ucy9wdWJsaWNhdGlvbnMvbG9jYWwtcHJvY3VyZW1lbnQtYWNjb3JkKQotIFtBY2NvcmQgNDogR3JlZW4gRWNvbm9teSBBY2NvcmRdKGh0dHA6Ly93d3cuZWNvbm9taWMuZ292LnphL2NvbW11bmljYXRpb25zL3B1YmxpY2F0aW9ucy9ncmVlbi1lY29ub215LWFjY29yZCkKLSBbQWNjb3JkIDY6IFlvdXRoIEVtcGxveW1lbnQgQWNjb3JkXShodHRwOi8vd3d3LmVjb25vbWljLmdvdi56YS9jb21tdW5pY2F0aW9ucy9wdWJsaWNhdGlvbnMveW91dGgtZW1wbG95bWVudC1hY2NvcmQpCgpUaGUgTmF0aW9uYWwgRGV2ZWxvcG1lbnQgUGxhbiBjb25zaXN0cyBvZiBmaWZ0ZWVuIGNoYXB0ZXJzLiBBcyBhIHNpbmdsZSBkb2N1bWVudCBpdCBpcyA0ODkgcGFnZXMgbG9uZywgd2hpY2ggaXMgc2lnbmlmaWNhbnRseSBtb3JlIHRoYW4gYW55IG9mIHRoZSBwcmV2aW91cyBwbGFucy4gSGVuY2UsIGZvciBjb21wdXRhdGlvbmFsIHJlYXNvbnMsIGl0IHdhcyBpbmNsdWRlZCBpbiB0aGUgYW5hbHlzaXMgYXMgc2VwYXJhdGUgY2hhcHRlcnMgcmF0aGVyIHRoYW4gb25lIGRvY3VtZW50LiBPdmVyYWxsLCAyNCBkb2N1bWVudHMgd2VyZSB1c2VkIGluIHRoZSBhbmFseXNpcy4KCkFsbCB0aGUgZG9jdW1lbnRzIHdlcmUgY29udmVydGVkIGludG8gcGxhaW4gdGV4dCBmaWxlcy4gQ29udmVyc2lvbiBmcm9tIFBERiB0byBwbGFpbiB0ZXh0IGxlZCB0byBtdWx0aXBsZSBlcnJvcnMgYXBwZWFyaW5nIGR1ZSB0byBzb21lIGhpc3RvcmljYWwgYW5kIG5vIGxvbmdlciBzdXBwb3J0ZWQgZm9udHMgY29tcHJvbWlzaW5nIHRoZSBjb252ZXJzaW9uLiBIZW5jZSBhbGwgdGhlIGRvY3VtZW50cyB3ZXJlIHNwZWxsLWNoZWNrZWQgdG8gY2FwdHVyZSBtb3N0IG9idmlvdXMgdHlwb3MuIAoKVXNpbmcgUiBzdGF0aXN0aWNhbCBzb2Z0d2FyZSwgcGxhaW4gdGV4dCB2ZXJzaW9ucyBvZiBuYXRpb25hbCBkZXZlbG9wbWVudCBwbGFucyB3ZXJlIGluZ2VzdGVkIGFuZCBhICJjb3JwdXMiIG9iamVjdCBmb3IgYW5hbHlzaXMgd2FzIGNyZWF0ZWQgKHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9UZXh0X2NvcnB1cyBmb3IgZ2VuZXJhbCBpbnRyb2R1Y3Rpb24gdG8gdGhlIGNvbmNlcHQpLgoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiNMb2FkaW5nIHBhY2thZ2VzIGFuZCBkYXRhCmxpYnJhcnkocmVhZHRleHQpCmxpYnJhcnkocXVhbnRlZGEpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJ3b3JsZG1hcCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkoY2xhc3NJbnQpCmxpYnJhcnkodmVnYW4pCmxpYnJhcnkoYm9vdCkKbGlicmFyeShoYXZlbikKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkodGV4cmVnKQpsaWJyYXJ5KHJhbmRvbUZvcmVzdCkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShzdG0pCmBgYAoKCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpEQVRBX0RJUiA8LSAiLi4vZGF0YS8iIAoKbmRwX2ZpbGVzIDwtIHJlYWR0ZXh0KHBhc3RlMChEQVRBX0RJUiwgImNvbnZlcnRlZC9uZHBzLyoiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3ZhcnNmcm9tID0gImZpbGVuYW1lcyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdnNlcD0iXyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N2YXJuYW1lcyA9IGMoIlBsYW4iLCAiQXR0cmlidXRlIikpCgpuZHBfZmlsZXMkZG9jX2lkIDwtIHN0cl9yZXBsYWNlKG5kcF9maWxlcyRkb2NfaWQsICIudHh0IiwgIiIpIAoKYGBgCgpUaGUgdGFibGUgYmVsb3cgcHJvdmlkZXMgc3VtbWFyeSBpbmZvcm1hdGlvbiBmb3Igb3VyIGNvcnB1cy4gCgpgYGB7ciBlY2hvPUZBTFNFfQpuZHBfY29ycHVzIDwtIGNvcnB1cyhuZHBfZmlsZXMsIHRleHRfZmllbGQgPSAidGV4dCIsIGRvY2lkX2ZpZWxkID0gImRvY19pZCIpIApzdW1fZGF0YSA8LSBzdW1tYXJ5KG5kcF9jb3JwdXMpCnN1bW1hcnkgPC0gc3VtX2RhdGEgJT4lCnNlbGVjdChUeXBlcywgVG9rZW5zLCBTZW50ZW5jZXMsIFBsYW4pICU+JQpncm91cF9ieShQbGFuKSAlPiUKc3VtbWFyaXNlKFR5cGVzID0gc3VtKFR5cGVzKSwgVG9rZW5zID0gc3VtKFRva2VucyksIFNlbnRlbmNlcyA9IHN1bShTZW50ZW5jZXMpKQpzdW1tYXJ5CgpgYGAKCldlIG9ic2VydmUgYSBkcmFtYXRpYyBpbmNyZWFzZSBpbiBzaXplIG9mIHRoZSBwbGFucyBvdmVyIHRpbWUuIFRoaXMgaXMgcGFydGljdWxhcmx5IHRydWUgZm9yIE5EUCwgd2hpY2ggc3RhbmRzIGF0IDE2MiwwNTYgdG90YWwgd29yZHMgYW5kIDYsNjI3IHNlbnRlbmNjZXMuIEFub3RoZXIgd2F5IHRvIGxvb2sgYXQgdGhlIGRpdmVyc2l0eSBvZiBjb250ZW50IGluIHBsYW5zIGlzIGZvY3VzaW5nIG9uIHR5cGVzIC0tIGRpc3RpbmN0IHdvcmRzLiBORFAgaGFzIDMyLDk2NSB0eXBlcyB3aGljaCBpcyBtb3JlIHRoYW4gdGhyZWUgdGltZXMgaGlnaGVyIHRoYW4gdGhlIHNlY29uZCBsYXJnZXN0IG51bWJlciBpbiBOR1AgYW5kIGFsbW9zdCB0d2VudHkgdGltZXMgaGlnaGVyIHRoYW4gaW4gQXNnaVNBLiBUaGF0IG1heSByZWZsZWN0IG1vcmUgZGl2ZXJzZSBpc3N1ZXMgdGhhdCBhcmUgYmVpbmcgZGlzY3Vzc2VkIGluIE5EUC4gCgpUaGUgY29ycHVzIHdhcyB0aGVuIHRyYW5zZm9ybWVkIGludG8gc2VwYXJhdGUgd29yZHMgKHRva2VucyksIGFjY29tcGFuaWVkIGJ5IGJhc2ljIHByZS1wcm9jZXNzaW5nOiAKCi0gcmVtb3ZpbmcgcHVuY3R1YXRpb247Ci0gcmVtb3Zpbmcgc3ltYm9sczsKLSByZW1vdmluZyBudW1iZXJzOwotIHJlbW92aW5nIHR3aXR0ZXItcmVsYXRlZCBzeW1ib2xzOwotIHJlbW92aW5nIGVtYmVkZGVkIFVSTHM7Ci0gcmVtb3ZpbmcgaHlwaGVucy4gCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQojVG9rZW5pemF0aW9uIGFuZCBiYXNpYyBwcmUtcHJvY2Vzc2luZwp0b2sgPC0gdG9rZW5zKG5kcF9jb3JwdXMsIHdoYXQgPSAid29yZCIsCiAgICAgICAgICAgICAgcmVtb3ZlX3B1bmN0ID0gVFJVRSwKICAgICAgICAgICAgICByZW1vdmVfc3ltYm9scyA9IFRSVUUsCiAgICAgICAgICAgICAgcmVtb3ZlX251bWJlcnMgPSBUUlVFLAogICAgICAgICAgICAgIHJlbW92ZV90d2l0dGVyID0gVFJVRSwKICAgICAgICAgICAgICByZW1vdmVfdXJsID0gVFJVRSwKICAgICAgICAgICAgICByZW1vdmVfaHlwaGVucyA9IFRSVUUsCiAgICAgICAgICAgICAgdmVyYm9zZSA9IFRSVUUpCmBgYAoKQWRkaXRpb25hbGx5LCBhbnkgZGlnaXRzIGFuZCBwdW5jdHVhdGlvbiB0aGF0IG1heSBiZSBwYXJ0IG9mIHRva2VucyB0aHJvdWdoIG1pc3Rha2VzIGluIHRleHQgY29udmVyc2lvbiBhbmQgaW5wdXQgd2VyZSBhbHNvIHJlbW92ZWQuIEFueSB0b2tlbnMgY29udGFpbmluZyBsZXNzIHRoYW4gdGhyZWUgY2hhcmFjdGVycyBsb25nIHdlcmUgcmVtb3ZlZCBhcyB3ZWxsLiBUaGlzIHBpY2tzIHVwIHNvbWUgYWRkaXRpb25hbCBtaXN0YWtlcyBhbmQgdHlwb3MuIE5leHQgYWxsIHRva2VucyB3ZXJlIGNvbnZlcnRlZCBpbnRvIGxvd2VyIGNhc2UuIAoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CiNSZW1vdmluZyBhbnkgZGlnaXRzIGFuZCBwdW5jdHVhdGlvbiwgdGhhdCBtYXkgYmUgcGFydCBvZiB0b2tlbnMgKHRocm91Z2ggbWlzdGFrZXMgaW4gUERGIHRvIHRleHQgY29udmVyc2lvbikuCiNSZW1vdmluZyBhbnkgdG9rZW5zIGxlc3MgdGhhbiB0aHJlZSBjaGFyYWN0ZXJzLgojTG93ZXIgY2FzZSBldmVyeXRoaW5nCnRvay5tIDwtIHRva2Vuc19zZWxlY3QodG9rLCBjKCJbXFxkLV0iLCJeLnsxLDJ9JCIsICJbWzpwdW5jdDpdXSIpLCAKICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24gPSAicmVtb3ZlIiwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWV0eXBlPSJyZWdleCIsIHZlcmJvc2UgPSBUUlVFKQoKdG9rLnIgPC0gdG9rZW5zX3RvbG93ZXIodG9rLm0pCgpgYGAKCkEgZG9jdW1lbnQgZmVhdHVyZSBtYXRyaXggKGFrYSBkb2N1bWVudCB0ZXJtIG1hdHJpeCkgb3IgREZNIGlzIGEgZnVuZGFtZW50YWwgaW5wdXQgaW50byBuYXR1cmFsIGxhbmd1YWdlIHByb2Nlc3NpbmcgKHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Eb2N1bWVudC10ZXJtX21hdHJpeCkuIFdlIGNvbnN0cnVjdCBhIERGTSBmcm9tIHRva2VucyBhZnRlciBzdGVtbWluZyBhbmQgcmVtb3ZpbmcgInN0b3Agd29yZHMiIChub3QgY2FycnlpbmcgZnVuY3Rpb25hbCBtZWFuaW5nKSB1c2luZyB0aGUgW1NNQVJUXShodHRwOi8vZG9jcy5xdWFudGVkYS5pby9yZWZlcmVuY2Uvc3RvcHdvcmRzLmh0bWwpIGxpc3QuIAoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CgpkZm0gPC0gZGZtKHRvay5yLCAKICAgICAgICAgICB0b2xvd2VyID0gVFJVRSwKICAgICAgICAgICByZW1vdmU9IHN0b3B3b3JkcygiU01BUlQiKSwKICAgICAgICAgICBzdGVtPVRSVUUsIAogICAgICAgICAgIHZlcmJvc2UgPSBUUlVFKQoKdG9wZmVhdHVyZXMoZGZtLCBuID0gNTAsIGRlY3JlYXNpbmcgPSBGQUxTRSkKCmBgYAoKVGhlIERGTSBpcyB0cmltbWVkIGJ5IGRyb3BwaW5nIHRva2VucyBhcHBlYXJpbmcgbGVzcyB0aGFuIHRocmVlIHRpbWVzLCBtYWlubHkgdG8gY2F0Y2ggdHlwb3MgYW5kIHRleHQgY29udmVyc2lvbiBtaXN0YWtlcy4gVGhlIGxvZ2ljIGlzIHRoYXQgaWYgYSB0b2tlbiBpcyB1c2VkIG9ubHkgb25jZSBpbiBhbGwgZG9jdW1lbnRzLCB0aGF0IGNvdWxkIGJlIGEgZmVhdHVyZSB0aGF0IGRvZXMgbm90IGRpc3Rpbmd1aXNoIHdlbGwgYmV0d2VlbiBkb2N1bWVudHMuIEFsdGVybmF0aXZlbHkgdGhhdCBjYW4gYmUgYSBzcGVsbGluZyBtaXN0YWtlIG9yIHR5cG8uIFRvdGFsIG51bWJlciBvZiB0b2tlbnMgKDMxMzUpIHNob3dzIHRoZSBzaXplIG9mIHRoZSB0cmltbWVkIERGTSB0aGF0IHdlIHVzZSBpbiB0aGUgYW5hbHlzaXMuCgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CiNEcm9wcGluZyB3b3JkcyB0aGF0IGFwcGVhciBsZXNzIHRoYW4gMyB0aW1lcy4KZGZtLnRyaW0gPC0gZGZtX3RyaW0oZGZtLCBtaW5fY291bnQgPSAzKQoKdG9wZmVhdHVyZXMoZGZtLnRyaW0sIG4gPSA1MCwgZGVjcmVhc2luZyA9IEZBTFNFKQoKc3BhcnNpdHkoZGZtLnRyaW0pCgpuZmVhdHVyZShkZm0udHJpbSkKYGBgCgoKCiMjIEZyZXF1ZW5jeSBhbmQga2V5bmVzcyBhbmFseXNpcwoKSW4gb3VyIGNvcnB1cyBhcyBhIHdob2xlLCB3ZSBjYW4gYXNzZXNzIHRoZSBtb3N0IGZyZXF1ZW50bHkgb2NjdXJyaW5nIHRlcm1zIGluIG91ciBjb3JwdXMsIHdpdGggdGhlIHZpc3VhbGlzYXRpb24gYmVsb3cgZm9jdXNpbmcgb24gdGhlIDIwIG1vc3QgZnJlcXVlbnQgd29yZHMuCgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KZnJlcSA8LSB0ZXh0c3RhdF9mcmVxdWVuY3koZGZtLnRyaW0pCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxWzE6NTAsIF0sIGFlcyh4ID0gcmVvcmRlcihmZWF0dXJlLCBmcmVxdWVuY3kpLCB5ID0gZnJlcXVlbmN5KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHggPSBOVUxMLCB5ID0gIkZyZXF1ZW5jeSIpCmBgYAoKCgpGb3IgY29udmVuaWVuY2UsIHRoZSBzYW1lIGluZm9ybWF0aW9uIGlzIHByZXNlbnRlZCBhcyBhIHRyYWRpdGlvbmFsIHdvcmQgY2xvdWQgKHdpdGggMTAwIG1vc3QgZnJlcXVlbnQgdGVybXMpLiAKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0udHJpbSwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCldlIGNhbiBhbHNvIGFzc2VzcyBkaWZmZXJlbmNlcyBpbiBmcmVxdWVuY3kgb2Ygd29yZCB1c2FnZSBieSBkZXZlbG9wbWVudCBwbGFucy4gVGhpcyBoaWdobGlnaHRzIHRoZSBldm9sdXRpb24gb2YgbW9zdCBmcmVxdWVudGx5IG9jY3VycmluZyB0ZXJtcyAoYW5kIHRodXMgc2FsaWVuY3kgb2YgdGhlIHRlcm1zKSBvdmVyIHRpbWUuIAoKIyMjIFJEUAoKV29yZGNsb3VkIHBsb3Qgb2YgMTAwIG1vc3QgZnJlcXVlbnQgdGVybXMgaW4gUkRQOiAKCmBgYHtyIGVjaG89RkFMU0V9CmRmbS5yZHAgPC0gZGZtX3N1YnNldChkZm0udHJpbSwgUGxhbj09IlJEUCIpCnRleHRwbG90X3dvcmRjbG91ZChkZm0ucmRwLCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKV2UgY2FuIGV4cGxvcmUgd2hpY2gga2V5IHRlcm1zIGFwcGVhciBpbiBSRFAgbW9yZSBmcmVxdWVudGx5IHRoYW4gYnkgY2hhbmNlIHVzaW5nIHRoZSBjb25jZXB0IG9mIFtrZXluZXNzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9LZXl3b3JkXyhsaW5ndWlzdGljcykuIFdlIGNhbGN1bGF0ZSBrZXluZXNzIGZvciBSRFAgY29tcGFyZWQgdG8gYWxsIG90aGVyIGRvY3VtZW50cyBpbiBvdXIgY29ycHVzIChyZW1haW5pbmcgZGV2ZWxvcG1lbnQgcGxhbnMpLiBUaGUgb3V0cHV0cyBhcmUgc29ydGVkIGluIGRlc2NlbmRpbmcgb3JkZXIgYnkgdGhlIGFzc29jaWF0aW9uIG1lYXN1cmUgKGNoaTIgaGVyZSkuIEZpZ3VyZSBiZWxvdyB2aXN1YWxpc2VzIGtleW5lc3MgYmV0d2VlbiBSRFAgYW5kIG90aGVyIGRldmVsb3BtZW50IHBsYW5zOiAKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzX3JkcCA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLCBkb2N2YXJzKG5kcF9jb3JwdXMsICJQbGFuIikgPT0gIlJEUCIsICBzb3J0ID0gVFJVRSkKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzX3JkcCwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIlJEUCIsICJPdGhlciBkZXZlbG9wbWVudCBwbGFucyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgUkRQIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuNywgMC4zKSkgKyB5bGltKC0yMDAsIDEzMDApCmBgYAoKVGVybXMgb24gdGhlIHJpZ2h0IChpbiByZWQpIGFyZSB3b3JkcyB0aGF0IGFwcGVhciBzaWduaWZpY2FudGx5IG1vcmUgZnJlcXVlbnRseSBpbiBSRFAgdGhhbiB3b3VsZCBiZSBleHBlY3RlZCBieSBjaGFuY2UgY29tcGFyZWQgdG8gYWxsIG90aGVyIG5hdGlvbmFsIGRldmVsb3BtZW50IHBsYW5zLiBGb3IgZXhhbXBsZSwgImRlbW9jcmF0IiwgInJlY29uc3RydWN0IiwgInByb2dyYW1tIiwgYW5kICJhcGFydGhlaWQiLiBBdCB0aGUgc2FtZSB0aW1lLCB0aGUgdGVybXMgb24gdGhlIGxlZnQgKGluIGJsdWUpIGFwcGVhciBsZXNzIGZyZXF1ZW50bHkgdGhhbiBpbiBvdGhlciBkb2N1bWVudHM6IGUuZy4sICJncm93dGgiLCAidGFyZ2V0IiwgInNwYXRpYWwiLiAKCiMjIyBHRUFSCmBgYHtyIGVjaG89RkFMU0V9CmRmbS5nZWFyIDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0sIFBsYW49PSJHRUFSIikKdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS5nZWFyLCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzX2dlYXIgPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbSwgZG9jdmFycyhuZHBfY29ycHVzLCAiUGxhbiIpID09ICJHRUFSIiwgIHNvcnQgPSBUUlVFKQp0ZXh0cGxvdF9rZXluZXNzKGtleW5lc3NfZ2Vhciwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgKyB5bGltKC0xMDAsIDgwMCkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIkdFQVIiLCAiT3RoZXIgZG9jdW1lbnRzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBHRUFSIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuOCwgMC4zKSkKYGBgCgpJbiBHRUFSIG1vcmUgcHJvbWluZW50IHRlcm1zIGFyZSBhcm91bmQgd2FnZXMgYW5kIGVtcGxveW1lbnQsIGRlZmljaXQsIGV4cGVuZGl0dXJlLCBhbmQgZmlzY2FsIGlzc3Vlcy4gCgoKIyMjIEFzZ2lTQQpgYGB7ciBlY2hvPUZBTFNFfQpkZm0uYXNnaXNhIDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0sIFBsYW49PSJBc2dpU0EiKQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLmFzZ2lzYSwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzX2FzZ2lzYSA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLCBkb2N2YXJzKG5kcF9jb3JwdXMsICJQbGFuIikgPT0gIkFzZ2lTQSIsICBzb3J0ID0gVFJVRSkKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzX2FzZ2lzYSwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgKyB5bGltKC0xMDAsIDgwMCkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIkFzZ2lTQSIsICJPdGhlciBkb2N1bWVudHMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIEFzZ2lTQSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjgsIDAuMykpCmBgYAoKQXNnaVNBIG1vc3QgcHJvbWluZW50IHRlcm1zIGFyZSBwcm9qZWN0IGFjcm9ueW1zIHBvaW50aW5nIHRvIG1vcmUgaW5zdGl0dXRpb24gcmF0aGVyIHRoYW4gcG9saWN5IGZvY3VzLiAKCgojIyMgTkdQCmBgYHtyIGVjaG89RkFMU0V9CmRmbS5uZ3AgPC0gZGZtX3N1YnNldChkZm0udHJpbSwgUGxhbj09Ik5HUCIpCnRleHRwbG90X3dvcmRjbG91ZChkZm0ubmdwLCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzX25ncCA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLCBkb2N2YXJzKG5kcF9jb3JwdXMsICJQbGFuIikgPT0gIk5HUCIsICBzb3J0ID0gVFJVRSkKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzX25ncCwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIk5HUCIsICJPdGhlciBkb2N1bWVudHMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIE5HUCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjcsIDAuMykpICsgeWxpbSgtMzAwLCAyMDAwKQpgYGAKCk5HUCBpcyBpbnRyb2R1Y2luZyBhIHNldCBvZiBjb21taXRtZW50cyBhbmQgcmVmZXJlbmNlcyB0byBncmVlbiBncm93dGgsIGFuZCBqb2JzLiAKCgoKIyMjIE5EUAoKYGBge3IgZWNobz1GQUxTRX0KZGZtLm5kcCA8LSBkZm1fc3Vic2V0KGRmbS50cmltLCBQbGFuPT0iTkRQIikKdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS5uZHAsIG1heC53b3Jkcz0xMDAsIHNjYWxlPWMoMiwuNSksIHJhbmRvbS5vcmRlcj1GQUxTRSkKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc19uZHAgPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbSwgZG9jdmFycyhuZHBfY29ycHVzLCAiUGxhbiIpID09ICJORFAiLCAgc29ydCA9IFRSVUUpCnRleHRwbG90X2tleW5lc3Moa2V5bmVzc19uZHAsIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICsgeWxpbSgtNTAwLCAyMDApICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJORFAiLCAiT3RoZXIgZG9jdW1lbnRzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBORFAiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4zLCAwLjgpKQpgYGAKCk5EUCBpcyBpbnRlcmVzdGluZyBpbiB0aGF0IGl0IGhhcyByZWxhdGl2ZWx5IGZld2VyIG1lbnRpb25zIG9mIGVjb25vbWljIGdyb3d0aCwgZW1wbG95bWVudCwgYW5kIHJlYWwgc2VjdG9yIHJlbGF0ZWQgdGVybXMuIFdoYXQgc2V0cyBORFAgYXBhcnQgZnJvbSBwcmV2aW91cyBkZXZlbG9wbWVudCBwbGFucyBpcyBpdHMgZW1waGFzaXMgb2YgaGVhbHRoIGFuZCBsb3cgY2FyYm9uIGVjb25vbXksIGFuZCBjb3JydXB0aW9uIHJlbGF0ZWQgaXNzdWVzLiAgCgoKCiMjIFRvcGljIG1vZGVsaW5nCgpJbiB0aGUgdG9waWMgbW9kZWwgYW5hbHlzaXMgd2UgY29uc2lkZXIgdGhlIHRoZW1hdGljIHN0cnVjdHVyZSBvZiBkZXZlbG9wbWVudCBwbGFucyBhbmQgZWZmZWN0IG9mIHN0cnVjdHVyYWwgdmFyaWFibGVzLiBHaXZlbiBsaW1pdGVkIG51bWJlciBvZiBkb2N1bWVudHMgaW4gdGhpcyBwYXJ0IG9mIHRoZSBhbmFseXNpcywgd2UgYXJlIG9ubHkgbG9va2luZyBhdCB0aGVtYXRpYyBkaWZmZXJlbmNlcyBhY3Jvc3MgZG9jdW1lbnRzIGFzIHN0cnVjdHVyYWwgZWZmZWN0cy4gVGhhdCBpcyB3aGV0aGVyIHRoZW1lcyBjaGFuZ2UgYWNyb3NzIGRldmVsb3BtZW50IHBsYW5zLiBJbiBvcmRlciB0byBhY2hpZXZlIHRoYXQgd2UgaW1wbGVtZW50IGEgc3RydWN0dXJhbCB0b3BpYyBtb2RlbCAoUm9iZXJ0cyBldCBhbC4sIDIwMTYpLiBXZSBtb2RlbCB0b3BpYyBwcmV2YWxlbmNlIGluIHRoZSBjb250ZXh0IG9mIHRoZSBkZXZlbG9wbWVudCBwbGFuIGNvdmFyaWF0ZSAoYSBmYWN0b3IgdmFyaWFibGUgd2l0aCBhIGxldmVsIGZvciBlYWNoIGluZGl2aWR1YWwgcGxhbikuIFRoZSBhaW0gaXMgdG8gc3RhdGlzdGljYWxseSB0ZXN0IHdoZXRoZXIgdGhlIG1ldGFkYXRhIGFmZmVjdHMgdGhlIGZyZXF1ZW5jeSB3aXRoIHdoaWNoIGEgdG9waWMgaXMgZGlzY3Vzc2VkIGluIGRldmVsb3BtZW50IHBsYW5zIC0tIHRoZSBhdmVyYWdlIHByb3BvcnRpb24gb2YgYSBkb2N1bWVudCBkaXNjdXNzaW5nIGEgdG9waWMuIAoKU3RydWN0dXJhbCB0b3BpYyBtb2RlbCBvciBTVE0gKFJvYmVydHMgZXQgYWwuLCAyMDE2KSBpcyBhIHR5cGUgb2YgcHJvYmFiaWxpc3RpYyB0b3BpYyBtb2RlbHMgKEJsZWkgZXQgYWwuIDIwMDMpIHRoYXQgYWxsb3dzIHRvIGFzc2VzcyB0aGUgZWZmZWN0IG9mIGNvdmFyaWF0ZXMgKHNlZSBodHRwOi8vd3d3LnN0cnVjdHVyYWx0b3BpY21vZGVsLmNvbTsgZm9yIGFuIGludHJvZHVjdGlvbiBhbmQgYSBuaWNlIG92ZXJ2aWV3IG9mIHRvcGljIG1vZGVsaW5nIHNlZSBodHRwOi8vd3d3LmNzLmNvbHVtYmlhLmVkdS9+YmxlaS9wYXBlcnMvQmxlaTIwMTIucGRmKS4KCiMjI1NlYXJjaGluZyBmb3Igb3B0aW1hbCBudW1iZXIgb2YgdG9waWNzCgpPbmUga2V5IGlucHV0IGludG8gdGhlIHRvcGljIG1vZGVsaW5nIGFsZ29yaXRobSBpcyBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgdG9waWNzIHRoZSBhbGdvcml0aG0gbmVlZHMgdG8gdW5jb3ZlciBpbiB0aGUgY29ycHVzLiBUaGlzIGNhbiBiZSBkb25lIHdpdGggYSBtYW51YWwgaW5wdXQsIHVzaW5nIGh1bWFuIGV4cGVydCBqdWRnZW1lbnQgdG8gZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgdG9waWNzLiBBbHRlcm5hdGl2ZWx5LCB0aGlzIGNhbiBiZSBkb25lIGJ5IGZvY3VzaW5nIG9uIHNlbWFudGljIGNvaGVyZW5jZSAoc2VlIE1pbW5vIGV0IGFsLiwgMjAxMSkgYW5kIGV4Y2x1c2l2aXR5IChzZWUgQmlzY2hvZiBhbmQgQWlyb2xkaSwgMjAxMikgbWVhc3VyZXMuIEhpZ2hseSBmcmVxdWVudCB3b3JkcyBpbiBhIGdpdmVuIHRvcGljIHRoYXQgZG9uJ3QgYXBwZWFyIHRvbyBvZnRlbiBpbiBvdGhlciB0b3BpY3MgYXJlIHNhaWQgdG8gbWFrZSB0aGF0IHRvcGljIGV4Y2x1c2l2ZS4gQ29oZXNpdmUgYW5kIGV4Y2x1c2l2ZSB0b3BpY3MgYXJlIG1vcmUgc2VtYW50aWNhbGx5IHVzZWZ1bC4gCgpXZSBmaXJzdCBnZW5lcmF0ZSBhIHNldCBvZiBjYW5kaWRhdGUgbW9kZWxzLCBoZXJlIHJhbmdpbmcgYmV0d2VlbiAzIGFuZCAzMCB0b3BpY3MuIFRoZW4gd2UgcGxvdCBleGNsdXNpdml0eSBhbmQgc2VtYW50aWMgY29oZXJlbmNlIGVzdGltYXRlcyBmb3IgZWFjaCBjYW5kaWRhdGUgbW9kZWwgYW5kIGNob29zZSB0aGUgb3B0aW1hbCBudW1iZXIgb2YgdG9waWNzIGFzIGEgYmFsYW5jZSBiZXR3ZWVuIHRoZXNlIHR3byBtZWFzdXJlcyAoc2VlIFJvYmVydHMgZXQgYWwuLCAyMDE2KS4KCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQpzdG0uZGZtIDwtIGNvbnZlcnQoZGZtLnRyaW0sIHRvID0gInN0bSIsICBkb2N2YXJzID0gZG9jdmFycyhuZHBfY29ycHVzKSkKYGBgCgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Kc2VhcmNoIDwtIHNlYXJjaEsoc3RtLmRmbSRkb2N1bWVudHMsIHN0bS5kZm0kdm9jYWIsIAogICAgICAgICAgICAgICAgICBwcmV2YWxlbmNlID0gfiBmYWN0b3IoUGxhbiksCiAgICAgICAgICAgICAgICAgIEsgPSBjKDM6MzApLAogICAgICAgICAgICAgICAgICBkYXRhID0gc3RtLmRmbSRtZXRhLCBtYXguZW0uaXRzPTIwMDApCgpzZWFyY2gucmVzdWx0cyA8LSBhcy5kYXRhLmZyYW1lKHNlYXJjaCRyZXN1bHRzKQpyZWFkcjo6d3JpdGVfY3N2KHNlYXJjaC5yZXN1bHRzLCAic2VhcmNoLnJlc3VsdHMuY3N2IikKYGBgCgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CnNlYXJjaF9yZXN1bHRzIDwtIHJlYWRyOjpyZWFkX2Nzdigic2VhcmNoLnJlc3VsdHMuY3N2IikKYGBgCgpQbG90IGJlbG93IG1hcHMgZXhjbHVzaXZpdHkgYW5kIHNlbWFudGljIGNvaGVyZW5jZSAobnVtYmVycyBjbG9zZXIgdG8gemVybyBpbmRpY2F0ZSBoaWdoZXIgY29oZXJlbmNlKSwgYW5kIHNlbGVjdCBhIG1vZGVsIG9uIHRoZSBzZW1hbnRpYyBjb2hlcmVuY2UtZXhjbHVzaXZpdHkgImZyb250aWVyIiAod2hlcmUgbm8gbW9kZWwgc3RyaWN0bHkgZG9taW5hdGVzIGFub3RoZXIgaW4gdGVybXMgb2Ygc2VtYW50aWMgY29oZXJlbmNlIGFuZCBleGNsdXNpdml0eSkuIAoKYGBge3IsIGVjaG89RkFMU0V9CnBhcihtYXI9Yyg1LDQsNCw1KSsuMSkKcGxvdChzZWFyY2hfcmVzdWx0cyRLLHNlYXJjaF9yZXN1bHRzJGV4Y2x1cyx0eXBlPSJsIixjb2w9InJlZCIsIAogICAgIHhsYWI9Ik51bWJlciBvZiB0b3BpY3MiLCB5bGFiPSJFeGNsdXNpdml0eSIpCmF4aXMoc2lkZT0xLGF0PTkpCmFibGluZSh2PTksIGNvbD0iZ3JlZW4iKQpwYXIobmV3PVRSVUUpCnBsb3Qoc2VhcmNoX3Jlc3VsdHMkSywgc2VhcmNoX3Jlc3VsdHMkc2VtY29oLAogICAgIHR5cGU9ImwiLGNvbD0iYmx1ZSIseGF4dD0ibiIseWF4dD0ibiIseGxhYj0iIix5bGFiPSIiKQpheGlzKDQpCm10ZXh0KCJTZW1hbnRpYyBDb2hlcmVuY2UiLHNpZGU9NCxsaW5lPTMpCmxlZ2VuZCgicmlnaHQiLGNvbD1jKCJyZWQiLCJibHVlIiksbHR5PTEsbGVnZW5kPWMoImV4Y2wiLCJzZW0gY29oIikpCgpgYGAKCgpUaGUgbW9kZWwgd2l0aCBuaW5lIHRvcGljcyBpcyBzZWxlY3RlZCBmb3Igb3VyIGFuYWx5c2lzIChoaWdobGlnaHRlZCB3aXRoIHZlcnRpY2FsIGxpbmUpLiBUaGVyZSdzIGEgc2hhcnAgZHJvcCBpbiBzZW1hbnRpYyBjb2hlcmVuY2UgYWZ0ZXIgJGs9OSQuIAoKCgojIyMgU3RydWN0dXJhbCB0b3BpYyBtb2RlbCB3aXRoIDkgdG9waWNzCgoKYGBge3IgZXZhbD1UUlVFLCBpbmNsdWRlPUZBTFNFfQoKdG9waWNzOSA8LSBzdG0oc3RtLmRmbSRkb2N1bWVudHMsIHN0bS5kZm0kdm9jYWIsICAKICAgICAgICAgICAgICAgcHJldmFsZW5jZSA9IH4gZmFjdG9yKFBsYW4pLCAKICAgICAgICAgICAgICAgZGF0YSA9IHN0bS5kZm0kbWV0YSwgCiAgICAgICAgICAgICAgIEsgPSA5LCBpbml0LnR5cGUgPSAiU3BlY3RyYWwiKQoKYGBgCgoKT25lIHdheSB0byBzdW1tYXJpemUgdG9waWNzIGlzIHRvIGNvbWJpbmUgdGVybSBmcmVxdWVuY3kgYW5kIGV4Y2x1c2l2aXR5IHRvIHRoYXQgdG9waWMgaW50byBhIHVuaXZhcmlhdGUgc3VtbWFyeSBzdGF0aXN0aWMuIEluIFNUTSBwYWNrYWdlIGluIFIgdGhpcyBpcyBpbXBsZW1lbnRlZCBhcyBGUkVYIChzZWUgQmlzY2hvZiBhbmQgQWlyb2xkaSwgMjAxMiBhbmQgQWlyb2xkaSBhbmQgQmlzY2hvZiwgMjAxNikuIFRoZSBsb2dpYyBiZWhpbmQgdGhpcyBtZWFzdXJlIGlzIHRoYXQgYm90aCBmcmVxdWVuY3kgYW5kIGV4Y2x1c2l2aXR5IGFyZSBpbXBvcnRhbnQgZmFjdG9ycyBpbiBkZXRlcm1pbmluZyBzZW1hbnRpYyBjb250ZW50IG9mIGEgd29yZCBhbmQgZm9ybSBhIHR3byBkaW1lbnNpb25hbCBzdW1tYXJ5IG9mIHRvcGljYWwgY29udGVudC4gRlJFWCBpcyB0aGUgZ2VvbWV0cmljIGF2ZXJhZ2Ugb2YgZnJlcXVlbmN5IGFuZCBleGNsdXNpdml0eSBhbmQgY2FuIGJlIHZpZXdlZCBhcyBhIHVuaXZhcmlhdGUgbWVhc3VyZSBvZiB0b3BpY2FsIGltcG9ydGFuY2UuIAoKU1RNIGF1dGhvcnMgc3VnZ2VzdCB0aGF0IG5vbmV4Y2x1c2l2ZSB3b3JkcyBhcmUgbGVzcyBsaWtlbHkgdG8gY2FycnkgdG9waWMtc3BlY2lmaWMgY29udGVudCwgd2hpbGUgaW5mcmVxdWVudCB3b3JkcyBvY2N1ciB0b28gcmFyZWx5IHRvIGZvcm0gdGhlIHNlbWFudGljIGNvcmUgb2YgYSB0b3BpYy4gRlJFWCBpcyB0aGVyZWZvcmUgY29tYmluaW5nIGluZm9ybWF0aW9uIGZyb20gdGhlIG1vc3QgZnJlcXVlbnQgd29yZHMgaW4gdGhlIGNvcnB1cyB0aGF0IGFyZSBhbHNvIGxpa2VseSB0byBoYXZlIGJlZW4gZ2VuZXJhdGVkIGZyb20gdGhlIHRvcGljIG9mIGludGVyZXN0IHRvIHN1bW1hcml6ZSBpdHMgY29udGVudC4gCgpUaGUgdGFibGUgYmVsb3cgcHJlc2VudHMgZm91ciB0eXBlcyBvZiB3b3JkIHdlaWdodGluZ3MgdXNpbmcgYWx0ZXJuYXRpdmUgbWVhc3VyZXMuIEhpZ2hlc3QgcHJvYmFiaWxpdHkgd29yZHMgbGlzdCB0aGUgd29yZHMgd2l0aGluIGVhY2ggdG9waWMgd2l0aCB0aGUgaGlnaGVzdCBwcm9iYWJpbGl0eS4gRlJFWCBhcmUgdGhlIHdvcmRzIHJhbmtlZCBieSB0aGVpciBmcmV4IG1lYXN1cmUgZGlzY3Vzc2VkIGFib3ZlLiBMaWZ0IGlzIGNhbGN1bGF0ZWQgYnkgZGl2aWRpbmcgdGhlIHRvcGljLXdvcmQgZGlzdHJpYnV0aW9uIGJ5IHRoZSBlbXBpcmljYWwgd29yZCBjb3VudCBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24uIFNpZXZlcnQgYW5kIFNoaXJsZXkgKDIwMTQpIHBvaW50IHRoYXQgdGhlIF9saWZ0XyBtZWFzdXJlIChUYWRkeSAyMDExKSBhaW1zIHRvIGRlLXJhbmsgaGlnaC1mcmVxdWVuY3kgdGVybXMsIGJ1dCBpbiBwcmFjdGljZSBpdCBvZnRlbiBnaXZlcyBoaWdoIHJhbmtpbmcgdG8gdmVyeSByYXJlIHRlcm1zIG9jY3VycmluZyBpbiBvbmx5IGEgc2luZ2xlIHRvcGljLiBTY29yZSBpcyBhIG1ldHJpYyB1c2VkIGluIHRoZSBfbGRhXyBSIHBhY2thZ2UgYnkgSm9uYXRoYW4gQ2hhbmcuCgpJbiBwcmFjdGljZSwgbWFudWFsIHRvcGljIGxhYmVsaW5nIGlzIHVzdWFsbHkgZXZhbHVhdGVkIHRocm91Z2ggYSBjb21iaW5hdGlvbiBvZiB0aGUgbWV0cmljcyBiZWxvdy4gCgpgYGB7ciwgZWNobz1GQUxTRX0KbGFiZWxUb3BpY3ModG9waWNzOSwgbiA9IDEwKQpgYGAKCk1hbnVhbGx5IGFzc2Vzc2luZyB0aGUgd29yZCB3ZWlnaHRpbmdzIGFjcm9zcyB0aGUgZm91ciBtZXRyaWNzIGFib3ZlIHdlIGNhbiBpbnRyb2R1Y2UgdGhlIGZvbGxvd2luZyBsYWJlbHM6CgotICoqVG9waWMgMToqKiBFY29ub21pYyBncm93dGgKLSAqKlRvcGljIDI6KiogRWR1Y2F0aW9uCi0gKipUb3BpYyAzOioqIEhlYWx0aAotICoqVG9waWMgNDoqKiBTa2lsbHMgYW5kIHRyYWluaW5nCi0gKipUb3BpYyA1OioqIEdyZWVuIGVjb25vbXkKLSAqKlRvcGljIDY6KiogUmVjb25zdHJ1Y3Rpb24gYW5kIGRlbW9jcmFjeQotICoqVG9waWMgNzoqKiBDbGltYXRlIGNoYW5nZSBhbmQgcmVzb3VyY2VzCi0gKipUb3BpYyA4OioqIENvcnJ1cHRpb24gYW5kIHNlY3VyaXR5Ci0gKipUb3BpYyA5OioqIEZpc2NhbCBwb2xpY3kgYW5kIG1hY3JvZWNvbm9teQoKVGhpcyBsYWJlbGluZyBpcyBhbiBvdXRzaWRlciBpbnRlcnByZXRhdGlvbiBvZiB0aGUgd29yZCB3ZWlnaHRpbmdzIGFuZCB3aWxsIG5lY2Vzc2FyaWx5IGNoYW5nZSB3aXRoIG1vcmUgZG9tYWluIGV4cGVydGlzZSBicm91Z2h0IGluIHRvIGxhYmVsIHRoZSB0b3BpY3MuIAoKRmlndXJlIGJlbG93IGRpc3BsYXlzIHRoZSB0b3BpY3Mgb3JkZXJlZCBieSB0aGVpciBleHBlY3RlZCBmcmVxdWVuY3kgYWNyb3NzIHRoZSBjb3JwdXMsIHdpdGggaWxsdXN0cmF0aXZlIHRvcCBGUkVYIHdvcmRzLgoKYGBge3IsIGVjaG89RkFMU0V9CnBsb3QodG9waWNzOSx0eXBlPSJzdW1tYXJ5IiwgIG4gPSAxMCwgdGV4dC5jZXggPSAuNCwgbGFiZWx0eXBlID0gImZyZXgiKQoKYGBgCgoKCiMjIyBUb3BpY2FsIGRpZmZlcmVuY2UgYWNyb3NzIHByb2dyYW1tZXMKCkluIHRoZSBTVE0gZnJhbWV3b3JrIHdlIGNhbiBlc3RpbWF0ZSB0aGUgZWZmZWN0IG9mIGV4dGVybmFsIGNvdmFyaWF0ZXMuIEFzIG1lbnRpb25lZCBhYm92ZSwgaGVyZSBleHRlcm5hbCBjb3ZhcmlhdGVzIGFyZSBsaW1pdGVkIHRvIGRpZmZlcmVuY2VzIGFjcm9zcyBkZXZlbG9wbWVudCBwcm9ncmFtbWVzLiBUaGlzIGlzIGR1ZSB0byB0aGUgZmFjdCB0aGF0IGl0J3MgZGlmZmljdWx0IHRvIHVuYW1iaWd1b3VzbHkgYXR0cmlidXRlIGVjb25vbWljIGluZGljYXRvcnMgbGlrZSBpbmZsYXRpb24gb3IgdW5lbXBsb3ltZW50IHJhdGVzIHRvIGRvY3VtZW50cyB0aGF0IHNwYW4gc2V2ZXJhbCB5ZWFycyBpbiBwcmVwYXJhdGlvbiBhbmQgaW1wbGVtZW50YXRpb24uCgpFc3RpbWF0aW9uIGlzIGRvbmUgd2l0aCBhIGxpbmVhciByZWdyZXNzaW9uIHdoZXJlIGRvY3VtZW50cyBhcmUgdGhlIHVuaXRzLCB0aGUgb3V0Y29tZSBpcyB0aGUgcHJvcG9ydGlvbiBvZiBlYWNoIGRvY3VtZW50IGFib3V0IGEgdG9waWMgaW4gYW4gU1RNIG1vZGVsIGFuZCB0aGUgY292YXJpYXRlIGlzIHRoZSBmYWN0b3IgdmFyaWFibGUgZm9yIG5hdGlvbmFsIGRldmVsb3BtZW50IHByb2dyYW1tZXMuIEVzdGltYXRpb24gaW5jb3Jwb3JhdGVzIG1lYXN1cmVtZW50IHVuY2VydGFpbnR5IGZyb20gdGhlIFNUTSBtb2RlbCB1c2luZyB0aGUgbWV0aG9kIG9mIGNvbXBvc2l0aW9uLgoKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQpjb24uZWZmIDwtIGVzdGltYXRlRWZmZWN0KH4gZmFjdG9yKFBsYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3BpY3M5LCBtZXRhID0gc3RtLmRmbSRtZXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB1bmNlcnRhaW50eSA9ICJHbG9iYWwiKQoKYGBgCgpQbG90cyBiZWxvdyBkaXNwbGF5IHRoZSBlZmZlY3Qgb2Ygb3VyIGNvdmFyaWF0ZSBvbiBlYWNoIGVzdGltYXRlZCB0b3BpYy4gVGhlIGNvdmFyaWF0ZSBpcyBhIG5vbWluYWwgZml2ZS1sZXZlbCBmYWN0b3IgdmFyaWFibGUgZm9yIGVhY2ggZGV2ZWxvcG1lbnQgcGxhbi4gV2UgZXN0aW1hdGUgbWVhbiB0b3BpYyBwcm9wb3J0aW9ucyBmb3IgZWFjaCB2YWx1ZSBvZiB0aGUgY292YXJpYXRlLCB3aXRoIGNvcnJlc3BvbmRpbmcgOTVcJSBjb25maWRlbmNlIGludGVydmFscyBvZiB0aGUgZWZmZWN0LiAgCgpgYGB7ciwgZWNobz1GQUxTRX0KCnBsb3QoY29uLmVmZiwgY292YXJpYXRlID0gIlBsYW4iLCAgdG9waWNzID0gMSwKICAgICBtb2RlbCA9IHRvcGljczksIG1ldGhvZCA9ICJwb2ludGVzdGltYXRlIiwgCiAgICAgbWFpbiA9ICJUb3BpYyAxIiwKICAgICBjb3YudmFsdWUxID0gIlBsYW4iLCB4bGltID0gYygtLjgsIC44KSwgbGFiZWx0eXBlPSJjdXN0b20iLAogICAgIGN1c3RvbS5sYWJlbHMgPSBjKCJBc2dpU0EiLCAiR0VBUiIsICJORFAiLCAiTkdQIiwgIlJEUCIpKQoKYGBgCgoKCgoKYGBge3IsIGVjaG89RkFMU0V9CgpwbG90KGNvbi5lZmYsIGNvdmFyaWF0ZSA9ICJQbGFuIiwgIHRvcGljcyA9IDIsCiAgICAgbW9kZWwgPSB0b3BpY3M5LCBtZXRob2QgPSAicG9pbnRlc3RpbWF0ZSIsIAogICAgIG1haW4gPSAiVG9waWMgMiIsCiAgICAgY292LnZhbHVlMSA9ICJQbGFuIiwgeGxpbSA9IGMoLS44LCAuOCksIGxhYmVsdHlwZT0iY3VzdG9tIiwKICAgICBjdXN0b20ubGFiZWxzID0gYygiQXNnaVNBIiwgIkdFQVIiLCAiTkRQIiwgIk5HUCIsICJSRFAiKSkKCmBgYAoKVG9waWNzIDEgKEVjb25vbWljIGdyb3d0aCkgYW5kIDIgKEVkdWNhdGlvbikgYXBwZWFyIGluIGFsbCBkZXZlbG9wbWVudCBwcm9ncmFtbWVzIGluIHNpbWlsYXIgcHJvcG9ydGlvbnMgaGlnaGxpZ2h0aW5nIHRoZWlyIHN0YWJsZSBpbXBvcnRhbmNlIG92ZXIgdGltZS4gCgoKCmBgYHtyLCBlY2hvPUZBTFNFfQoKcGxvdChjb24uZWZmLCBjb3ZhcmlhdGUgPSAiUGxhbiIsICB0b3BpY3MgPSAzLAogICAgIG1vZGVsID0gdG9waWNzOSwgbWV0aG9kID0gInBvaW50ZXN0aW1hdGUiLCAKICAgICBtYWluID0gIlRvcGljIDMiLAogICAgIGNvdi52YWx1ZTEgPSAiUGxhbiIsIHhsaW0gPSBjKC0uOCwgLjgpLCBsYWJlbHR5cGU9ImN1c3RvbSIsCiAgICAgY3VzdG9tLmxhYmVscyA9IGMoIkFzZ2lTQSIsICJHRUFSIiwgIk5EUCIsICJOR1AiLCAiUkRQIikpCgpgYGAKClRvcGljIDMgKEhlYWx0aCkgaXMgZ2l2ZW4gaGlnaGVyIG9mIHRoZSBORFAgY29tcGFyZWQgdG8gb3RoZXIgZGV2ZWxvcG1lbnQgcHJvZ3JhbW1lcy4gCgoKYGBge3IsIGVjaG89RkFMU0V9CgpwbG90KGNvbi5lZmYsIGNvdmFyaWF0ZSA9ICJQbGFuIiwgIHRvcGljcyA9IDQsCiAgICAgbW9kZWwgPSB0b3BpY3M5LCBtZXRob2QgPSAicG9pbnRlc3RpbWF0ZSIsIAogICAgIG1haW4gPSAiVG9waWMgNCIsCiAgICAgY292LnZhbHVlMSA9ICJQbGFuIiwgeGxpbSA9IGMoLS44LCAxLjUpLCBsYWJlbHR5cGU9ImN1c3RvbSIsCiAgICAgY3VzdG9tLmxhYmVscyA9IGMoIkFzZ2lTQSIsICJHRUFSIiwgIk5EUCIsICJOR1AiLCAiUkRQIikpCgpgYGAKCgpUb3BpYyA0IChTa2lsbHMgYW5kIHRyYWluaW5nKSBpcyBnaXZlbiBoaWdoZXIgYXR0ZW50aW9uIGluIEFzZ2lTQSBjb21wYXJlZCB0byBvdGhlciBwcm9ncmFtbWVzLCB3aXRoIHRoZSBleGNlcHRpb24gb2YgTkdQIHRoYXQgaXMgYWxzbywgYWxiZWl0IHN0YXRpc3RpY2FsbHkgbWFyZ2luYWxseSwgaGFzIGxhcmdlciBjb3ZlcmFnZSBvZiB0aGUgdG9waWMuCgoKCmBgYHtyLCBlY2hvPUZBTFNFfQoKcGxvdChjb24uZWZmLCBjb3ZhcmlhdGUgPSAiUGxhbiIsICB0b3BpY3MgPSA1LAogICAgIG1vZGVsID0gdG9waWNzOSwgbWV0aG9kID0gInBvaW50ZXN0aW1hdGUiLCAKICAgICBtYWluID0gIlRvcGljIDUiLAogICAgIGNvdi52YWx1ZTEgPSAiUGxhbiIsIHhsaW0gPSBjKC0uOCwgLjgpLCBsYWJlbHR5cGU9ImN1c3RvbSIsCiAgICAgY3VzdG9tLmxhYmVscyA9IGMoIkFzZ2lTQSIsICJHRUFSIiwgIk5EUCIsICJOR1AiLCAiUkRQIikpCgpgYGAKClRvcGljIDUgKEdyZWVuIGVjb25vbXkpIGlzIGdpdmVuIGhpZ2hlciBhdHRlbnRpb24gaW4gTkdQIGNvbXBhcmVkIHRvIG90aGVyIGRldmVsb3BtZW50IHByb2dyYW1tZXMuCgoKCmBgYHtyLCBlY2hvPUZBTFNFfQoKcGxvdChjb24uZWZmLCBjb3ZhcmlhdGUgPSAiUGxhbiIsICB0b3BpY3MgPSA2LAogICAgIG1vZGVsID0gdG9waWNzOSwgbWV0aG9kID0gInBvaW50ZXN0aW1hdGUiLCAKICAgICBtYWluID0gIlRvcGljIDYiLAogICAgIGNvdi52YWx1ZTEgPSAiUGxhbiIsIHhsaW0gPSBjKC0uOCwgMS41KSwgbGFiZWx0eXBlPSJjdXN0b20iLAogICAgIGN1c3RvbS5sYWJlbHMgPSBjKCJBc2dpU0EiLCAiR0VBUiIsICJORFAiLCAiTkdQIiwgIlJEUCIpKQoKYGBgCgoKVG9waWMgNiAoUmVjb25zdHJ1Y3Rpb24gYW5kIGRlbW9jcmFjeSkgaGFzIGEgaGlnaCBjb3ZlcmFnZSBpbiBSRFAsIGFzIHdvdWxkIGJlIGV4cGVjdGVkIGZyb20gdGhlIGVhcmx5IG5hdGlvbmFsIGRldmVsb3BtZW50IHBsYW4uCgoKCmBgYHtyLCBlY2hvPUZBTFNFfQoKcGxvdChjb24uZWZmLCBjb3ZhcmlhdGUgPSAiUGxhbiIsICB0b3BpY3MgPSA3LAogICAgIG1vZGVsID0gdG9waWNzOSwgbWV0aG9kID0gInBvaW50ZXN0aW1hdGUiLCAKICAgICBtYWluID0gIlRvcGljIDciLAogICAgIGNvdi52YWx1ZTEgPSAiUGxhbiIsIHhsaW0gPSBjKC0xLCAxKSwgbGFiZWx0eXBlPSJjdXN0b20iLAogICAgIGN1c3RvbS5sYWJlbHMgPSBjKCJBc2dpU0EiLCAiR0VBUiIsICJORFAiLCAiTkdQIiwgIlJEUCIpKQoKYGBgCgoKCgpgYGB7ciwgZWNobz1GQUxTRX0KCnBsb3QoY29uLmVmZiwgY292YXJpYXRlID0gIlBsYW4iLCAgdG9waWNzID0gOCwKICAgICBtb2RlbCA9IHRvcGljczksIG1ldGhvZCA9ICJwb2ludGVzdGltYXRlIiwgCiAgICAgbWFpbiA9ICJUb3BpYyA4IiwKICAgICBjb3YudmFsdWUxID0gIlBsYW4iLCB4bGltID0gYygtLjgsIC44KSwgbGFiZWx0eXBlPSJjdXN0b20iLAogICAgIGN1c3RvbS5sYWJlbHMgPSBjKCJBc2dpU0EiLCAiR0VBUiIsICJORFAiLCAiTkdQIiwgIlJEUCIpKQoKYGBgCgoKVG9waWNzIDcgKENsaW1hdGUgY2hhbmdlIGFuZCByZXNvdXJjZXMpIGFuZCA4IChDb3JydXB0aW9uIGFuZCBzZWN1cml0eSkgaGF2ZSBoaWdoZXIgY292ZXJhZ2UgaW4gdGhlIG1vc3QgcmVjZW50IG5hdGlvbmFsIGRldmVsb3BtZW50IHByb2dyYW1tZSAoTkRQKS4KCgpgYGB7ciwgZWNobz1GQUxTRX0KCnBsb3QoY29uLmVmZiwgY292YXJpYXRlID0gIlBsYW4iLCAgdG9waWNzID0gOSwKICAgICBtb2RlbCA9IHRvcGljczksIG1ldGhvZCA9ICJwb2ludGVzdGltYXRlIiwgCiAgICAgbWFpbiA9ICJUb3BpYyA5IiwKICAgICBjb3YudmFsdWUxID0gIlBsYW4iLCB4bGltID0gYygtLjgsIDEuNSksIGxhYmVsdHlwZT0iY3VzdG9tIiwKICAgICBjdXN0b20ubGFiZWxzID0gYygiQXNnaVNBIiwgIkdFQVIiLCAiTkRQIiwgIk5HUCIsICJSRFAiKSkKCmBgYAoKVG9waWMgOSAoRmlzY2FsIHBvbGljeSBhbmQgbWFjcm9lY29ub215KSBoYXMgaGlnaGVyIGVtcGhhc2lzIGluIHRoZSAxOTk2IEdFQVIgcHJvZ3JhbW1lIGFuZCwgc3RhdGlzdGljYWxseSBtYXJnaW5hbGx5LCBpbiBORFAgY29tcGFyZWQgdG8gb3RoZXIgZGV2ZWxvcG1lbnQgcGxhbnMuICAgCgpUb3BpYyBtb2RlbGluZyByZXN1bHRzIGhpZ2hsaWdodCB0aGUgaXNzdWUgb2YgaXNzdWUgZGl2ZXJzaXR5IG1lbnRpb25lZCBlYWxyaWVyLiBGcm9tIG5pbmUgdG9waWNzIGlkZW50aWZpZWQgTkRQIGhhcyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHBvc2l0aXZlIGVmZmVjdCBvbiBmb3VyIHRvcGljcywgd2hpbGUgQXNnaVNBLCBHRUFSLCBSRFAgaGF2ZSBvbmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBlZmZlY3QgZWFjaCBhbmQgdHdvIGZvciBOR1AuCgojIyMgUmVsYXRpb25zaGlwIGJldHdlZW4gdG9waWNzCgpXZSBjYW4gYXNzZXNzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0b3BpY3MgaW4gdGhlIFNUTSBmcmFtZXdvcmsgdGhhdCBhbGxvd3MgY29ycmVsYXRpb25zIGJldHdlZW4gdG9waWNzLiBXZSBjYWxjdWxhdGUgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gZXN0aW1hdGVzIG9mIHRoZSB0b3BpYyBwcm9wb3J0aW9ucyBhbmQgZHJvcCBlZGdlcyBiZWxvdyB0aGUgY29ycmVsYXRpb24gdGhyZXNob2xkIDAuMDEuIFBvc2l0aXZlIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIHRvcGljcyBzdWdnZXN0IHRoYXQgYm90aCB0b3BpY3MgYXJlIGxpa2VseSB0byBiZSBjb3ZlcmVkIHdpdGhpbiBhIGRldmVsb3BtZW50IHByb2dyYW1tZS4KCmBgYHtyLCBlY2hvPUZBTFNFfQp0b3BpYy5jb3IgPC0gdG9waWNDb3JyKHRvcGljczkpCgpwbG90KHRvcGljLmNvcikKCmBgYAoKVHdvIHNldHMgb2YgdG9waWNzIGFyZSBjb25uZWN0ZWQgd2l0aCBlYWNoIG90aGVyOiBUb3BpY3MgMSBhbmQgOSwgYW5kIFRvcGljcyAyIGFuZCA1LiBXZSBjYW4gY29udHJhc3QgdGhlIHdvcmRzIGFjcm9zcyB0d28gY29ubmVjdGVkIHRvcGljcyBieSBjYWxjdWxhdGluZyB0aGUgZGlmZmVyZW5jZSBpbiBwcm9iYWJpbGl0eSBvZiBhIHdvcmQgZm9yIHRoZSB0d28gdG9waWNzLCBhbmQgbm9ybWFsaXppbmcgdGhlIG1heGltdW0gZGlmZmVyZW5jZSBpbiBwcm9iYWJpbGl0eSBvZiBhbnkgd29yZCBiZXR3ZWVuIHRoZSB0d28gdG9waWNzLiBUaGVzZSBhcmUgb2Z0ZW4gY2FsbGVkIHBlcnNwZWN0aXZlIHBsb3RzLCB3aGVyZSB3b3JkcyBhcmUgc2l6ZWQgcHJvcG9ydGlvbmFsIHRvIHRoZWlyIHVzZSB3aXRoaW4gdGhlIHBsb3R0ZWQgdG9waWMgY29tYmluYXRpb25zIGFuZCBvcmllbnRlZCBhbG9uZyB0aGUgWC1heGlzIGJhc2VkIG9uIGhvdyBtdWNoIHRoZXkgZmF2b3VyIGVhY2ggb2YgdGhlIHRvcGljcy4gVGhlIHZlcnRpY2FsIGNvbmZpZ3VyYXRpb24gb2YgdGhlIHdvcmRzIGlzIHJhbmRvbS4gIAoKSW50dWl0aXZlbHksIHRvcGljcyByZWxhdGVkIHRvIGVjb25vbWljIGdyb3d0aCAoVG9waWMgMSkgYW5kIGZpc2NhbCBwb2xpY3kgYW5kIG1hY3JvZWNvbm9teSAoVG9waWMgOSkgYXJlIHJlbGF0ZWQuIEhvd2V2ZXIsIHRoZSBwZXJzcGVjdGl2ZSBwbG90IGJlbG93IHJlbGF0aXZlIGVtcGhhc2VzIG9uIGRpZmZlcmVudCBhc3BlY3RzIGFjcm9zcyB0aGUgdG9waWNzLiBUaGUgd29yZHMgdGhhdCBzdHJhZGRsZSB0aGUgcHJvYmFiaWxpc3RpYyBib3VuZGFyeSBiZXR3ZWVuIHR3byB0b3BpY3MgcmVsYXRlIHRvIHNlcnZpY2VzIGFuZCBsYWJvdXIgbWFya2V0LiBUaGUgd29yZHMgbW9yZSBjZW50cmFsIHRvIGluZGl2aWR1YWwgdG9waWNzIGhpZ2hsaWdodCBhc3BlY3RzIG9mIGVjb25vbWljIGRldmVsb3BtZW50IHBvbGljaWVzLiAKCmBgYHtyLCBlY2hvPUZBTFNFfQoKcGxvdCh0b3BpY3M5LCB0eXBlID0gInBlcnNwZWN0aXZlcyIsIHRvcGljcyA9IGMoMSw5KSwgbj0yMCkKCmBgYAoKVG9waWNzIHJlbGF0ZWQgdG8gZWR1Y2F0aW9uIChUb3BpYyAyKSBhbmQgZ3JlZW4gZWNvbm9teSAoVG9waWMgNSkgYXJlIGFsc28gbW9yZSBsaWtlbHkgdG8gYmUgY292ZXJlZCBpbiB0aGUgc2FtZSBkZXZlbG9wbWVudCBwcm9ncmFtbWUuICAgIAoKYGBge3IsIGVjaG89RkFMU0V9CgpwbG90KHRvcGljczksIHR5cGUgPSAicGVyc3BlY3RpdmVzIiwgdG9waWNzID0gYygyLDUpLCBuPTIwKQoKYGBgCgoKIyMgVG9waWMgc2hhcmVzIHBlciBkZXZlbG9wbWVudCBwbGFuCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KHRpZHl0ZXh0KQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQphcF9kb2N1bWVudHMgPC0gdGlkeSh0b3BpY3M5LCBtYXRyaXggPSAiZ2FtbWEiLCBkb2N1bWVudF9uYW1lcyA9IHN0bS5kZm0kbWV0YSRQbGFuKSAKCnN1bXMgPC0gYXBfZG9jdW1lbnRzICU+JQpncm91cF9ieShkb2N1bWVudCwgdG9waWMpICU+JQpzdW1tYXJpc2UoVG9waWNfUHJvcG9ydGlvbiA9IHN1bShnYW1tYSkpICU+JSBhcnJhbmdlKHRvcGljLCBUb3BpY19Qcm9wb3J0aW9uKQprbml0cjo6a2FibGUoc3VtcykKYGBgCgpFYWNoIG9mIHRoZSB2YWx1ZXMgaW4gdGhlIHRhYmxlIGlzIGFuIGVzdGltYXRlZCBwcm9wb3J0aW9uIG9mIHdvcmRzIGZyb20gdGhhdCBkb2N1bWVudCB0aGF0IGFyZSBnZW5lcmF0ZWQgZnJvbSB0aGF0IHRvcGljLiBJdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IHByb3BvcnRpb25zIGRvIG5vdCBhZGQgdXAgdG8gMSBwZXIgZGV2ZWxvcG1lbnQgcGxhbi4gVGhpcyBpcyBiZWNhdXNlLCBhcyBtZW50aW9uZWQgZWFybGllciwgd2UgaW5jbHVkZWQgTkRQIGFuZCBOR1AgYXMgaW5kaXZpZHVhbCBjaGFwdGVycyBkdWUgdG8gbGFyZ2UgdGV4dCBsZW5ndGggaW1iYWxhbmNlLCB3aXRoIGVzdGltYXRlcyBmb3IgaW5kaXZpZHVhbCBjaGFwdGVycyBhZ2dyZWdhdGVkIGJ5IGRldmVsb3BtZW50IHBsYW4gZm9yIHByZXNlbnRhdGlvbiBvZiB0aGUgcmVzdWx0cy4gVGhlIG51bWJlcnMgb24gaW4gdGhlIHRhYmxlIGFib3ZlIHNob3VsZCBiZSB0cmVhdGVkIGFzIHJlbGF0aXZlIGluZGljYXRvcnMgb2YgdG9waWMgcHJldmFsZW5jZSBhY3Jvc3MgZG9jdW1lbnRzLiAgCgpUaGUgc2FtZSBpbmZvcm1haXRvbiBpcyBwcm92aWRlZCBpbiB0aGUgcGxvdHMgYmVsb3cgKHR3byB2YXJpYXRpb25zIGRpZmZlcmVudCBieSB0aGUgZm9jdXMgb2YgcHJlc2VudGF0aW9uIG9uIHRvcGljcyB2cyBkZXZlbG9wbWVudCBwbGFucykuCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3Qoc3VtcywgYWVzKHggPSByZW9yZGVyKGRvY3VtZW50LCBUb3BpY19Qcm9wb3J0aW9uKSwgCiAgICAgICAgICAgICAgICAgeSA9IFRvcGljX1Byb3BvcnRpb24sIGZpbGwgPSBmYWN0b3IodG9waWMpKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgZmFjZXRfd3JhcCh+IHRvcGljLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgIGNvb3JkX2ZsaXAoKSArIGxhYnMoeD0iIiwgeT0iIikKYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3Qoc3VtcywgYWVzKHggPSByZW9yZGVyKHRvcGljLCBUb3BpY19Qcm9wb3J0aW9uKSwgCiAgICAgICAgICAgICAgICAgeSA9IFRvcGljX1Byb3BvcnRpb24sIGZpbGwgPSBmYWN0b3IoZG9jdW1lbnQpKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgZmFjZXRfd3JhcCh+IGRvY3VtZW50LCBzY2FsZXMgPSAiZnJlZSIpICsKICAgIGNvb3JkX2ZsaXAoKSArIGxhYnMoeD0iIiwgeT0iIikKYGBgCgojIE5hdGlvbmFsIEJ1ZGdldCBSZXZpZXcgQW5hbHlzaXMKCiMjIERhdGEKClRoZSBkYXRhIGZvciB0aGlzIGFuYWx5c2lzIGNvbWVzIGZyb20gdGhlIFtOYXRpb25hbCBCdWRnZXQgUmV2aWV3c10oaHR0cDovL3d3dy50cmVhc3VyeS5nb3YuemEvZG9jdW1lbnRzL25hdGlvbmFsJTIwYnVkZ2V0L2RlZmF1bHQuYXNweCkuIFdlIGRvd25sb2FkZWQgYWxsIGNoYXB0ZXJzIChidXQgbm90IHRoZSBhcHBlbmRpY2VzKSwgYW5kIGNvbnZlcnRlZCBpbnRvIHBsYWluIHRleHQgZmlsZXMgd2l0aCBVVEY4IGVuY29kaW5nLiAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CkRBVEFfRElSIDwtICIuLi9kYXRhLyIgCgpidWRnZXRfZmlsZXMgPC0gcmVhZHRleHQocGFzdGUwKERBVEFfRElSLCAiY29udmVydGVkL2J1ZGdldHMvKiIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdmFyc2Zyb20gPSAiZmlsZW5hbWVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR2c2VwPSJfIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3Zhcm5hbWVzID0gYygiRG9jdW1lbnQiLCAiQ2hhcHRlciIsICJZZWFyIikpCgpidWRnZXRfZmlsZXMkZG9jX2lkIDwtIHN0cl9yZXBsYWNlKGJ1ZGdldF9maWxlcyRkb2NfaWQsICIudHh0IiwgIiIpIAoKYnVkZ2V0X2NvcnB1cyA8LSBjb3JwdXMoYnVkZ2V0X2ZpbGVzLCB0ZXh0X2ZpZWxkID0gInRleHQiLCBkb2NpZF9maWVsZCA9ICJkb2NfaWQiKSAKYGBgCgoKVGhlIHRhYmxlIGJlbG93IHByb3ZpZGVzIHN1bW1hcnkgaW5mb3JtYXRpb24gZm9yIG91ciBjb3JwdXMuIAoKYGBge3IgZWNobz1GQUxTRX0Kc3VtX2RhdGEgPC0gc3VtbWFyeShidWRnZXRfY29ycHVzKQoKc3VtbWFyeSA8LSBzdW1fZGF0YSAlPiUKc2VsZWN0KFllYXIsIFR5cGVzLCBUb2tlbnMsIFNlbnRlbmNlcykgJT4lCmdyb3VwX2J5KFllYXIpICU+JQpzdW1tYXJpc2UoVHlwZXMgPSBzdW0oVHlwZXMpLCBUb2tlbnMgPSBzdW0oVG9rZW5zKSwgU2VudGVuY2VzID0gc3VtKFNlbnRlbmNlcykpCnN1bW1hcnkKYGBgCgpXZSBhbHNvIHByZS1wcm9jZXNzZWQgdGhlIGNvcnB1cyBmb2xsb3dpbmcgdGhlIHNhbWUgc3RlcHMgYXMgYWJvdmUuIEluIGFkZGl0aW9uIHdlIGFsc28gcmVtb3ZlZCAiY2VudCIgYW5kICJiaWxsaW9uIiBmcm9tIHRoZSBjb3JwdXMgYXMsIGluIG91ciBzZXR0aW5nLCB0aGVzZSB3ZXJlIGhpZ2ggZnJlcXVlbmN5IG5vbi1mdW5jdGlvbiB3b3Jkcy4gCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQp0b2suYnVkZ2V0IDwtIHRva2VucyhidWRnZXRfY29ycHVzLCB3aGF0ID0gIndvcmQiLAogICAgICAgICAgICAgIHJlbW92ZV9wdW5jdCA9IFRSVUUsCiAgICAgICAgICAgICAgcmVtb3ZlX3N5bWJvbHMgPSBUUlVFLAogICAgICAgICAgICAgIHJlbW92ZV9udW1iZXJzID0gVFJVRSwKICAgICAgICAgICAgICByZW1vdmVfdHdpdHRlciA9IFRSVUUsCiAgICAgICAgICAgICAgcmVtb3ZlX3VybCA9IFRSVUUsCiAgICAgICAgICAgICAgcmVtb3ZlX2h5cGhlbnMgPSBUUlVFLAogICAgICAgICAgICAgIHZlcmJvc2UgPSBUUlVFKQoKCnRvay5tLmJ1ZCA8LSB0b2tlbnNfc2VsZWN0KHRvay5idWRnZXQsIGMoIltcXGQtXSIsIl4uezEsMn0kIiwgIltbOnB1bmN0Ol1dIiksIAogICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbiA9ICJyZW1vdmUiLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXR5cGU9InJlZ2V4IiwgdmVyYm9zZSA9IFRSVUUpCgp0b2suci5idWQgPC0gdG9rZW5zX3RvbG93ZXIodG9rLm0uYnVkKQpgYGAKCiMjIE92ZXJ2aWV3IG9mIE5CUiBjb3JwdXMKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQoKZGZtLmJ1ZGdldCA8LSBkZm0odG9rLnIuYnVkLCAKICAgICAgICAgICB0b2xvd2VyID0gVFJVRSwKICAgICAgICAgICByZW1vdmU9IGMoc3RvcHdvcmRzKCJTTUFSVCIpLCAiY2VudCIsImJpbGxpb24iKSwKICAgICAgICAgICBzdGVtPVRSVUUsIAogICAgICAgICAgIHZlcmJvc2UgPSBUUlVFKQoKZGZtLnRyaW0uYnVkZ2V0IDwtIGRmbV90cmltKGRmbS5idWRnZXQsIG1pbl9jb3VudCA9IDMpCgpgYGAKClRvdGFsIG51bWJlciBvZiB0b2tlbnMgaW4gTkJSIERGTSBpcyA0MDIzLiBUaGUgbW9zdCBmcmVxdWVudGx5IG9jY3VycmluZyB0ZXJtcyBhcmUgc2hvd24gYmVsb3cuIAoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmZyZXEuYnVkIDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0udHJpbS5idWRnZXQpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxLmJ1ZFsxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKQpgYGAKClZpc3VhbGlzZWQgYXMgYSB3b3JkY2xvdWQ6CgpgYGB7ciBlY2hvPUZBTFNFfQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLnRyaW0uYnVkZ2V0LCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCgojIyBNYXBwaW5nIG91dCBvdXRwdXQgc3RhYmlsaXNhdGlvbiBhbmQgY3JlZGliaWxpdHkgY29uY2VwdHMKCldlIGFzc2VzcyB0d28gY29uY2VwdHM6IG91dHB1dCBzdGFiaWxpc2F0aW9uIGFuZCBjcmVkaWJpbGl0eS4gRWFjaCBjb25jZXB0IGlzIGRlc2NyaWJlZCBieSBhIGxpc3Qgb2Yga2V5d29yZHMgbGlzdGVkIGJlbG93IHRoYXQgd2VyZSBwcm92aWRlZCBieSB0aGUgV29ybGQgQmFuazoKCi0gKipvdXRwdXQgc3RhYmlsaXNhdGlvbjoqKiBhdXRvbWF0aWMgc3RhYmlsaXplcnMsIHRheCBidW95YW5jeSwgY291bnRlcmN5Y2xpY2FsIGZpc2NhbCBwb2xpY3ksIGN5Y2xpY2FsbHkgYWRqdXN0ZWQgYnVkZ2V0IGJhbGFuY2UsIHN0cnVjdHVyYWwgYnVkZ2V0IGJhbGFuY2UsIGV4Y2hhbmdlIHJhdGUgYWJzb3JwdGlvbiwgc3RpbXVsdXMgcGFja2FnZSwgZmlzY2FsIHN0aW11bHVzLCBicmFja2V0IGNyZWVwIGFkanVzdG1lbnQsIHJlYmF0ZXMgaW5jcmVhc2UsIGV4cGFuc2lvbmFyeSBmaXNjYWwgcG9saWN5LCBhY2NvbW1vZGF0aW5nIGZpc2NhbCBwb2xpY3kKCi0gKipjcmVkaWJpbGl0eToqKiBzdXN0YWluYWJpbGl0eSwgbG93IHJpc2ssIG1lZXRpbmcgdGFyZ2V0cywgbG93IHZvbGF0aWxpdHksIHN1c3RhaW5hYmxlIGZpc2NhbCBwYXRoLCBsb3cgaW5mbGF0aW9uLCBtYXhpbWl6aW5nIGdyb3d0aCwgc3Ryb25nIG11bHRpcGxpZXJzCgoKV2l0aCB0aGUgbmVjZXNzYXJ5IGFkanVzdG1lbnQgZm9yIG11bHRpcGxlIHVzYWdlIGFuZCBzcGVsbGluZyB1c2VkIGluIE5CUiB0aGUgZGljdGlvbmFyeSBvZiBrZXl3b3JkcyB1c2VkIHdhcyBhcyBmb2xsb3dzIChhICIqIiBjaGFyYWN0ZXIgaW5kaWNhdGVzIGEgd2lsZC1jYXJkLCBpLmUuIHZlcnNpb25zIG9mIHdvcmQgZW5kaW5ncyk6CgpgYGB7ciBlY2hvPUZBTFNFfQpkaWN0IDwtIGRpY3Rpb25hcnkobGlzdChvdXRwdXRfc3RhYmlsaXNhdGlvbiA9IGMoImF1dG9tYXRpYyBzdGFiaWxpc2VyKiIsICJ0YXggYnVveWFuY3kiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY291bnRlcmN5Y2xpY2FsIGZpc2NhbCBwb2xpYyoiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImN5Y2xpY2FsbHkgYWRqdXN0ZWQgYnVkZ2V0IGJhbGFuY2UqIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdHJ1Y3R1cmFsIGJ1ZGdldCBiYWxhbmNlKiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXhjaGFuZ2UgcmF0ZSBhYnNvcnB0aW9uIiwgInN0aW11bHVzIHBhY2thZ2UqIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpc2NhbCBzdGltdWwqIiwgImJyYWNrZXQgY3JlZXAgYWRqdXN0bWVudCoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmViYXRlKiBpbmNyZWFzZSoiLCAiZXhwYW5zaW9uYXJ5IGZpc2NhbCBwb2xpYyoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWNjb21tb2RhdGluZyBmaXNjYWwgcG9saWMqIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZGliaWxpdHkgPSBjKCJzdXN0YWluYWJpbGl0eSIsICJsb3cgcmlzayoiLCAibWVldGluZyB0YXJnZXQqIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsb3cgdm9sYXRpbGl0eSIsICJzdXN0YWluYWJsZSBmaXNjYWwgcGF0aCIsICJsb3cgaW5mbGF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1heGltaXMqIGdyb3d0aCIsICJzdHJvbmcgbXVsdGlwbGllcioiKSkpCgoKZGljdAoKCnRvay5jb21wIDwtIHRva2Vuc19jb21wb3VuZCh0b2suci5idWQsIGRpY3QpCmBgYAoKRnJlcXVlbmN5IG9mIGJvdGggY29uY2VwdHMgYXBwZWFyaW5nIGluIE5CUiBpcyBwcmVzZW50ZWQgaW4gdGFibGUgYmVsb3cuIAoKYGBge3IgZWNobz1GQUxTRX0KZGF0YV94IDwtIGFzLmRhdGEuZnJhbWUoZGZtKHRvay5jb21wLCBkaWN0aW9uYXJ5ID1kaWN0KSkKCnRlbXAgPC0gYXMuZGF0YS5mcmFtZShzdHJfc3BsaXQocm93Lm5hbWVzKGRhdGFfeCksICJfIiwgc2ltcGxpZnkgPSBUUlVFKSkKCnN1bW1hcnlfZGF0YSA8LSBjYmluZChkYXRhX3gsdGVtcCkKCnN1bW1hcnlfZGF0YSRZZWFyIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHN1bW1hcnlfZGF0YSRWMykpCgpzdW1fa2V5d29yZHMgPC0gc3VtbWFyeV9kYXRhICU+JQpzZWxlY3QoWWVhciwgb3V0cHV0X3N0YWJpbGlzYXRpb24sIGNyZWRpYmlsaXR5KSAlPiUKZ3JvdXBfYnkoWWVhcikgJT4lCnN1bW1hcmlzZShPdXRwdXRfU3RhYmlsaXNhdGlvbiA9IHN1bShvdXRwdXRfc3RhYmlsaXNhdGlvbiksIENyZWRpYmlsaXR5ID0gc3VtKGNyZWRpYmlsaXR5KSkKc3VtX2tleXdvcmRzCgpgYGAKCgpUaGUgc2FtZSBpbmZvcm1hdGlvbiBpcyB2aXN1YWxpc2VkIGluIHRoZSBwbG90IGJlbG93OgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGRhdGEgPSBzdW1fa2V5d29yZHMsIGFlcyh4PVllYXIpKSsKICB0aGVtZV9idygpICsKICBnZ3RpdGxlKCJGaXNjYWwgcG9saWN5IGNyZWRpYmlsaXR5IikgKyAKICB5bGFiKCJUb3RhbCBudW1iZXIgb2YgbWVudGlvbnMgaW4gTkJSIikgKyB4bGFiKCJZZWFyIikgKwogIGdlb21fbGluZShhZXMoeT0gT3V0cHV0X1N0YWJpbGlzYXRpb24pLCBjb2xvdXIgPSAiYmx1ZSIsIGFscGhhID0gMC45KSArCiAgZ2VvbV9saW5lKGFlcyh5PSBDcmVkaWJpbGl0eSksIGNvbG91ciA9ICJyZWQiLCBhbHBoYSA9IDAuOSwgbGluZXR5cGU9ImRhc2hlZCIpICsKIyAgICBnZW9tX3BvaW50KGFlcyh5PSBtZWFuX2hlYWx0aCksIGNvbG91ciA9ICJibHVlIiwgYWxwaGEgPSAwLjksIHNoYXBlID0gMikgKwojICBnZW9tX3BvaW50KGFlcyh5ID0gbWVhbl9jbGltYXRlKSwgY29sb3VyID0gInJlZCIsIGFscGhhID0gMC45LCBzaGFwZSA9IDIxKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxOTk4LDIwMTcsMSkpICsKIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDIwMTAsIHkgPSAyMywgbGFiZWwgPSAiQ3JlZGliaWxpdHkiLCBjb2xvdXIgPSAicmVkIikrCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gMjAwNiwgeSA9IDE1LCBsYWJlbCA9ICJPdXRwdXQgU3RhYmlsaXNhdGlvbiIsIGNvbG91ciA9ICJibHVlIikgCgoKYGBgCgojIyBOQlIgZXhwbG9yYXRvcnkgYW5hbHlzaXMgYnkgeWVhcgoKIyMjIDE5OTgKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRmbS4xOTk4IDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0uYnVkZ2V0LCBZZWFyPT0xOTk4KQpmcmVxLjE5OTggPC0gdGV4dHN0YXRfZnJlcXVlbmN5KGRmbS4xOTk4KQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QoZnJlcS4xOTk4WzE6NTAsIF0sIGFlcyh4ID0gcmVvcmRlcihmZWF0dXJlLCBmcmVxdWVuY3kpLCB5ID0gZnJlcXVlbmN5KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHggPSBOVUxMLCB5ID0gIkZyZXF1ZW5jeSIpICsgZ2d0aXRsZSgiTkJSIDE5OTg6IFRvcCA1MCBtb3N0IGZyZXF1ZW50IHdvcmRzIikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS4xOTk4LCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzXzE5OTggPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbS5idWRnZXQsIGRvY3ZhcnMoYnVkZ2V0X2NvcnB1cywgIlllYXIiKSA9PSAxOTk4LCAgc29ydCA9IFRSVUUpCgp0ZXh0cGxvdF9rZXluZXNzKGtleW5lc3NfMTk5OCwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJOQlIgMTk5OCIsICJPdGhlciBOQlJzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBOQlIgMTk5OCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjEsIDAuOCkpIApgYGAKCgoKCiMjIyAxOTk5CgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMTk5OSA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MTk5OSkKZnJlcS4xOTk5IDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMTk5OSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMTk5OVsxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAxOTk5OiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMTk5OSwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18xOTk5IDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMTk5OSwgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzE5OTksIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDE5OTkiLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDE5OTkiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSArIHlsaW0oLTgwLDE1MCkKYGBgCgojIyMgMjAwMAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KZGZtLjIwMDAgPC0gZGZtX3N1YnNldChkZm0udHJpbS5idWRnZXQsIFllYXI9PTIwMDApCmZyZXEuMjAwMCA8LSB0ZXh0c3RhdF9mcmVxdWVuY3koZGZtLjIwMDApCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxLjIwMDBbMTo1MCwgXSwgYWVzKHggPSByZW9yZGVyKGZlYXR1cmUsIGZyZXF1ZW5jeSksIHkgPSBmcmVxdWVuY3kpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgY29vcmRfZmxpcCgpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSAiRnJlcXVlbmN5IikgKyBnZ3RpdGxlKCJOQlIgMjAwMDogVG9wIDUwIG1vc3QgZnJlcXVlbnQgd29yZHMiKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLjIwMDAsIG1heC53b3Jkcz0xMDAsIHNjYWxlPWMoMiwuNSksIHJhbmRvbS5vcmRlcj1GQUxTRSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRSxyZXN1bHRzPSAiaGlkZSIsZmlnLmtlZXA9ImFsbCJ9CmtleW5lc3NfMjAwMCA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLmJ1ZGdldCwgZG9jdmFycyhidWRnZXRfY29ycHVzLCAiWWVhciIpID09IDIwMDAsICBzb3J0ID0gVFJVRSkKCnRleHRwbG90X2tleW5lc3Moa2V5bmVzc18yMDAwLCBzaG93X3JlZmVyZW5jZSA9IFRSVUUsIG4gPSAyMEwsIG1pbl9jb3VudCA9IDJMKSAgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIk5CUiAyMDAwIiwgIk90aGVyIE5CUnMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIE5CUiAyMDAwIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC44KSkgKyB5bGltKC0xMDAsMjMwKQpgYGAKCgojIyMgMjAwMQoKYGBge3IgaW5jbHVkZT1GQUxTRX0KZGZtLjIwMDEgPC0gZGZtX3N1YnNldChkZm0udHJpbS5idWRnZXQsIFllYXI9PTIwMDEpCmZyZXEuMjAwMSA8LSB0ZXh0c3RhdF9mcmVxdWVuY3koZGZtLjIwMDEpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxLjIwMDFbMTo1MCwgXSwgYWVzKHggPSByZW9yZGVyKGZlYXR1cmUsIGZyZXF1ZW5jeSksIHkgPSBmcmVxdWVuY3kpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgY29vcmRfZmxpcCgpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSAiRnJlcXVlbmN5IikgKyBnZ3RpdGxlKCJOQlIgMjAwMTogVG9wIDUwIG1vc3QgZnJlcXVlbnQgd29yZHMiKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLjIwMDEsIG1heC53b3Jkcz0xMDAsIHNjYWxlPWMoMiwuNSksIHJhbmRvbS5vcmRlcj1GQUxTRSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRSxyZXN1bHRzPSAiaGlkZSIsZmlnLmtlZXA9ImFsbCJ9CmtleW5lc3NfMjAwMSA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLmJ1ZGdldCwgZG9jdmFycyhidWRnZXRfY29ycHVzLCAiWWVhciIpID09IDIwMDEsICBzb3J0ID0gVFJVRSkKCnRleHRwbG90X2tleW5lc3Moa2V5bmVzc18yMDAxLCBzaG93X3JlZmVyZW5jZSA9IFRSVUUsIG4gPSAyMEwsIG1pbl9jb3VudCA9IDJMKSAgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIk5CUiAyMDAxIiwgIk90aGVyIE5CUnMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIE5CUiAyMDAxIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC44KSkgKyB5bGltKC01MCwzMDApCmBgYAoKCiMjIyAyMDAyCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMjAwMiA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MjAwMikKZnJlcS4yMDAyIDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMjAwMCkKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMjAwMlsxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAyMDAyOiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMjAwMiwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18yMDAyIDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMjAwMiwgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzIwMDIsIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDIwMDIiLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDIwMDIiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSArIHlsaW0oLTUwLDIwMCkKYGBgCgoKCiMjIyAyMDAzCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMjAwMyA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MjAwMykKZnJlcS4yMDAzIDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMjAwMykKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMjAwM1sxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAyMDAzOiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMjAwMywgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18yMDAzIDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMjAwMywgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzIwMDMsIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDIwMDMiLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDIwMDMiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSAKYGBgCgoKCiMjIyAyMDA0CgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMjAwNCA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MjAwNCkKZnJlcS4yMDA0IDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMjAwNCkKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMjAwNFsxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAyMDA0OiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMjAwNCwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18yMDA0IDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMjAwNCwgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzIwMDQsIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDIwMDQiLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDIwMDQiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSArIHlsaW0oLTUwLDIyMCkKYGBgCgoKIyMjIDIwMDUKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRmbS4yMDA1IDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0uYnVkZ2V0LCBZZWFyPT0yMDA1KQpmcmVxLjIwMDUgPC0gdGV4dHN0YXRfZnJlcXVlbmN5KGRmbS4yMDA1KQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QoZnJlcS4yMDA1WzE6NTAsIF0sIGFlcyh4ID0gcmVvcmRlcihmZWF0dXJlLCBmcmVxdWVuY3kpLCB5ID0gZnJlcXVlbmN5KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHggPSBOVUxMLCB5ID0gIkZyZXF1ZW5jeSIpICsgZ2d0aXRsZSgiTkJSIDIwMDU6IFRvcCA1MCBtb3N0IGZyZXF1ZW50IHdvcmRzIikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS4yMDA1LCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzXzIwMDUgPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbS5idWRnZXQsIGRvY3ZhcnMoYnVkZ2V0X2NvcnB1cywgIlllYXIiKSA9PSAyMDA1LCAgc29ydCA9IFRSVUUpCgp0ZXh0cGxvdF9rZXluZXNzKGtleW5lc3NfMjAwNSwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJOQlIgMjAwNSIsICJPdGhlciBOQlJzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBOQlIgMjAwNSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjEsIDAuOCkpICsgeWxpbSgtMzAsIDEwMCkKYGBgCgoKIyMjIDIwMDYKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRmbS4yMDA2IDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0uYnVkZ2V0LCBZZWFyPT0yMDA2KQpmcmVxLjIwMDYgPC0gdGV4dHN0YXRfZnJlcXVlbmN5KGRmbS4yMDA2KQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QoZnJlcS4yMDA2WzE6NTAsIF0sIGFlcyh4ID0gcmVvcmRlcihmZWF0dXJlLCBmcmVxdWVuY3kpLCB5ID0gZnJlcXVlbmN5KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHggPSBOVUxMLCB5ID0gIkZyZXF1ZW5jeSIpICsgZ2d0aXRsZSgiTkJSIDIwMDY6IFRvcCA1MCBtb3N0IGZyZXF1ZW50IHdvcmRzIikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS4yMDA2LCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzXzIwMDYgPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbS5idWRnZXQsIGRvY3ZhcnMoYnVkZ2V0X2NvcnB1cywgIlllYXIiKSA9PSAyMDA2LCAgc29ydCA9IFRSVUUpCgp0ZXh0cGxvdF9rZXluZXNzKGtleW5lc3NfMjAwNiwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJOQlIgMjAwNiIsICJPdGhlciBOQlJzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBOQlIgMjAwNiIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjEsIDAuOCkpICsgeWxpbSgtODAsMzAwKQpgYGAKCgojIyMgMjAwNwoKYGBge3IgaW5jbHVkZT1GQUxTRX0KZGZtLjIwMDcgPC0gZGZtX3N1YnNldChkZm0udHJpbS5idWRnZXQsIFllYXI9PTIwMDcpCmZyZXEuMjAwNyA8LSB0ZXh0c3RhdF9mcmVxdWVuY3koZGZtLjIwMDcpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxLjIwMDdbMTo1MCwgXSwgYWVzKHggPSByZW9yZGVyKGZlYXR1cmUsIGZyZXF1ZW5jeSksIHkgPSBmcmVxdWVuY3kpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgY29vcmRfZmxpcCgpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSAiRnJlcXVlbmN5IikgKyBnZ3RpdGxlKCJOQlIgMjAwNzogVG9wIDUwIG1vc3QgZnJlcXVlbnQgd29yZHMiKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLjIwMDcsIG1heC53b3Jkcz0xMDAsIHNjYWxlPWMoMiwuNSksIHJhbmRvbS5vcmRlcj1GQUxTRSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRSxyZXN1bHRzPSAiaGlkZSIsZmlnLmtlZXA9ImFsbCJ9CmtleW5lc3NfMjAwNyA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLmJ1ZGdldCwgZG9jdmFycyhidWRnZXRfY29ycHVzLCAiWWVhciIpID09IDIwMDcsICBzb3J0ID0gVFJVRSkKCnRleHRwbG90X2tleW5lc3Moa2V5bmVzc18yMDA3LCBzaG93X3JlZmVyZW5jZSA9IFRSVUUsIG4gPSAyMEwsIG1pbl9jb3VudCA9IDJMKSAgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIk5CUiAyMDA3IiwgIk90aGVyIE5CUnMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIE5CUiAyMDA3IikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC44KSkgKyB5bGltKC01MCwyNTApCmBgYAoKCiMjIyAyMDA4CgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMjAwOCA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MjAwOCkKZnJlcS4yMDA4IDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMjAwOCkKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMjAwOFsxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAyMDA4OiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMjAwOCwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18yMDA4IDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMjAwOCwgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzIwMDgsIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDIwMDgiLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDIwMDgiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSArIHlsaW0oLTUwLDEwMCkKYGBgCgoKCiMjIyAyMDA5CgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMjAwOSA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MjAwOSkKZnJlcS4yMDA5IDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMjAwOSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMjAwOVsxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAyMDA5OiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMjAwOSwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18yMDA5IDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMjAwOSwgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzIwMDksIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDIwMDkiLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDIwMDkiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSArIHlsaW0oLTUwLDE1MCkKYGBgCgoKIyMjIDIwMTAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRmbS4yMDEwIDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0uYnVkZ2V0LCBZZWFyPT0yMDEwKQpmcmVxLjIwMTAgPC0gdGV4dHN0YXRfZnJlcXVlbmN5KGRmbS4yMDEwKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QoZnJlcS4yMDEwWzE6NTAsIF0sIGFlcyh4ID0gcmVvcmRlcihmZWF0dXJlLCBmcmVxdWVuY3kpLCB5ID0gZnJlcXVlbmN5KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHggPSBOVUxMLCB5ID0gIkZyZXF1ZW5jeSIpICsgZ2d0aXRsZSgiTkJSIDIwMTA6IFRvcCA1MCBtb3N0IGZyZXF1ZW50IHdvcmRzIikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS4yMDEwLCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzXzIwMTAgPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbS5idWRnZXQsIGRvY3ZhcnMoYnVkZ2V0X2NvcnB1cywgIlllYXIiKSA9PSAyMDEwLCAgc29ydCA9IFRSVUUpCgp0ZXh0cGxvdF9rZXluZXNzKGtleW5lc3NfMjAxMCwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJOQlIgMjAxMCIsICJPdGhlciBOQlJzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBOQlIgMjAxMCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjEsIDAuOCkpICsgeWxpbSgtNzAsMzAwKQpgYGAKCgoKIyMjIDIwMTEKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRmbS4yMDExIDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0uYnVkZ2V0LCBZZWFyPT0yMDExKQpmcmVxLjIwMTEgPC0gdGV4dHN0YXRfZnJlcXVlbmN5KGRmbS4yMDExKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QoZnJlcS4yMDExWzE6NTAsIF0sIGFlcyh4ID0gcmVvcmRlcihmZWF0dXJlLCBmcmVxdWVuY3kpLCB5ID0gZnJlcXVlbmN5KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHggPSBOVUxMLCB5ID0gIkZyZXF1ZW5jeSIpICsgZ2d0aXRsZSgiTkJSIDIwMTE6IFRvcCA1MCBtb3N0IGZyZXF1ZW50IHdvcmRzIikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS4yMDExLCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzXzIwMTEgPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbS5idWRnZXQsIGRvY3ZhcnMoYnVkZ2V0X2NvcnB1cywgIlllYXIiKSA9PSAyMDExLCAgc29ydCA9IFRSVUUpCgp0ZXh0cGxvdF9rZXluZXNzKGtleW5lc3NfMjAxMSwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJOQlIgMjAxMSIsICJPdGhlciBOQlJzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBOQlIgMjAxMSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjEsIDAuOCkpICsgeWxpbSgtOTAsNTAwKQpgYGAKCgoKIyMjIDIwMTIKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRmbS4yMDEyIDwtIGRmbV9zdWJzZXQoZGZtLnRyaW0uYnVkZ2V0LCBZZWFyPT0yMDEyKQpmcmVxLjIwMTIgPC0gdGV4dHN0YXRfZnJlcXVlbmN5KGRmbS4yMDEyKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QoZnJlcS4yMDEyWzE6NTAsIF0sIGFlcyh4ID0gcmVvcmRlcihmZWF0dXJlLCBmcmVxdWVuY3kpLCB5ID0gZnJlcXVlbmN5KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBsYWJzKHggPSBOVUxMLCB5ID0gIkZyZXF1ZW5jeSIpICsgZ2d0aXRsZSgiTkJSIDIwMTI6IFRvcCA1MCBtb3N0IGZyZXF1ZW50IHdvcmRzIikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KdGV4dHBsb3Rfd29yZGNsb3VkKGRmbS4yMDEyLCBtYXgud29yZHM9MTAwLCBzY2FsZT1jKDIsLjUpLCByYW5kb20ub3JkZXI9RkFMU0UpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UscmVzdWx0cz0gImhpZGUiLGZpZy5rZWVwPSJhbGwifQprZXluZXNzXzIwMTIgPC0gdGV4dHN0YXRfa2V5bmVzcyhkZm0udHJpbS5idWRnZXQsIGRvY3ZhcnMoYnVkZ2V0X2NvcnB1cywgIlllYXIiKSA9PSAyMDEyLCAgc29ydCA9IFRSVUUpCgp0ZXh0cGxvdF9rZXluZXNzKGtleW5lc3NfMjAxMiwgc2hvd19yZWZlcmVuY2UgPSBUUlVFLCBuID0gMjBMLCBtaW5fY291bnQgPSAyTCkgICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJOQlIgMjAxMiIsICJPdGhlciBOQlJzIikpICsgZ2d0aXRsZSgiS2V5bmVzcyBhbmFseXNpcyBvZiBOQlIgMjAxMiIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjEsIDAuOCkpICsgeWxpbSgtNTAsMTgwKQpgYGAKCgojIyMgMjAxMwoKYGBge3IgaW5jbHVkZT1GQUxTRX0KZGZtLjIwMTMgPC0gZGZtX3N1YnNldChkZm0udHJpbS5idWRnZXQsIFllYXI9PTIwMTMpCmZyZXEuMjAxMyA8LSB0ZXh0c3RhdF9mcmVxdWVuY3koZGZtLjIwMTMpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxLjIwMTNbMTo1MCwgXSwgYWVzKHggPSByZW9yZGVyKGZlYXR1cmUsIGZyZXF1ZW5jeSksIHkgPSBmcmVxdWVuY3kpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgY29vcmRfZmxpcCgpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSAiRnJlcXVlbmN5IikgKyBnZ3RpdGxlKCJOQlIgMjAxMzogVG9wIDUwIG1vc3QgZnJlcXVlbnQgd29yZHMiKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLjIwMTMsIG1heC53b3Jkcz0xMDAsIHNjYWxlPWMoMiwuNSksIHJhbmRvbS5vcmRlcj1GQUxTRSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRSxyZXN1bHRzPSAiaGlkZSIsZmlnLmtlZXA9ImFsbCJ9CmtleW5lc3NfMjAxMyA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLmJ1ZGdldCwgZG9jdmFycyhidWRnZXRfY29ycHVzLCAiWWVhciIpID09IDIwMTMsICBzb3J0ID0gVFJVRSkKCnRleHRwbG90X2tleW5lc3Moa2V5bmVzc18yMDEzLCBzaG93X3JlZmVyZW5jZSA9IFRSVUUsIG4gPSAyMEwsIG1pbl9jb3VudCA9IDJMKSAgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIk5CUiAyMDEzIiwgIk90aGVyIE5CUnMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIE5CUiAyMDEzIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC44KSkgKyB5bGltKC0xMDAsNDAwKQpgYGAKCgojIyMgMjAxNAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KZGZtLjIwMTQgPC0gZGZtX3N1YnNldChkZm0udHJpbS5idWRnZXQsIFllYXI9PTIwMTQpCmZyZXEuMjAxNCA8LSB0ZXh0c3RhdF9mcmVxdWVuY3koZGZtLjIwMTQpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxLjIwMTRbMTo1MCwgXSwgYWVzKHggPSByZW9yZGVyKGZlYXR1cmUsIGZyZXF1ZW5jeSksIHkgPSBmcmVxdWVuY3kpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgY29vcmRfZmxpcCgpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSAiRnJlcXVlbmN5IikgKyBnZ3RpdGxlKCJOQlIgMjAxNDogVG9wIDUwIG1vc3QgZnJlcXVlbnQgd29yZHMiKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLjIwMTQsIG1heC53b3Jkcz0xMDAsIHNjYWxlPWMoMiwuNSksIHJhbmRvbS5vcmRlcj1GQUxTRSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRSxyZXN1bHRzPSAiaGlkZSIsZmlnLmtlZXA9ImFsbCJ9CmtleW5lc3NfMjAxNCA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLmJ1ZGdldCwgZG9jdmFycyhidWRnZXRfY29ycHVzLCAiWWVhciIpID09IDIwMTQsICBzb3J0ID0gVFJVRSkKCnRleHRwbG90X2tleW5lc3Moa2V5bmVzc18yMDE0LCBzaG93X3JlZmVyZW5jZSA9IFRSVUUsIG4gPSAyMEwsIG1pbl9jb3VudCA9IDJMKSAgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIk5CUiAyMDE0IiwgIk90aGVyIE5CUnMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIE5CUiAyMDE0IikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC44KSkgKyB5bGltKC01MCwxNTApCmBgYAoKCgojIyMgMjAxNQoKYGBge3IgaW5jbHVkZT1GQUxTRX0KZGZtLjIwMTUgPC0gZGZtX3N1YnNldChkZm0udHJpbS5idWRnZXQsIFllYXI9PTIwMTUpCmZyZXEuMjAxNSA8LSB0ZXh0c3RhdF9mcmVxdWVuY3koZGZtLjIwMTUpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChmcmVxLjIwMTVbMTo1MCwgXSwgYWVzKHggPSByZW9yZGVyKGZlYXR1cmUsIGZyZXF1ZW5jeSksIHkgPSBmcmVxdWVuY3kpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgY29vcmRfZmxpcCgpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSAiRnJlcXVlbmN5IikgKyBnZ3RpdGxlKCJOQlIgMjAxNTogVG9wIDUwIG1vc3QgZnJlcXVlbnQgd29yZHMiKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFfQp0ZXh0cGxvdF93b3JkY2xvdWQoZGZtLjIwMTUsIG1heC53b3Jkcz0xMDAsIHNjYWxlPWMoMiwuNSksIHJhbmRvbS5vcmRlcj1GQUxTRSkKYGBgCgoKYGBge3IgZWNobz1GQUxTRSxyZXN1bHRzPSAiaGlkZSIsZmlnLmtlZXA9ImFsbCJ9CmtleW5lc3NfMjAxNSA8LSB0ZXh0c3RhdF9rZXluZXNzKGRmbS50cmltLmJ1ZGdldCwgZG9jdmFycyhidWRnZXRfY29ycHVzLCAiWWVhciIpID09IDIwMTUsICBzb3J0ID0gVFJVRSkKCnRleHRwbG90X2tleW5lc3Moa2V5bmVzc18yMDE1LCBzaG93X3JlZmVyZW5jZSA9IFRSVUUsIG4gPSAyMEwsIG1pbl9jb3VudCA9IDJMKSAgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iIiwgbGFiZWxzPWMoIk5CUiAyMDE1IiwgIk90aGVyIE5CUnMiKSkgKyBnZ3RpdGxlKCJLZXluZXNzIGFuYWx5c2lzIG9mIE5CUiAyMDE1IikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC44KSkgKyB5bGltKC04MCw0NTApCmBgYAoKCiMjIyAyMDE2CgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMjAxNiA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MjAxNikKZnJlcS4yMDE2IDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMjAxNikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMjAxNlsxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAyMDE2OiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMjAxNiwgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18yMDE2IDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMjAxNiwgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzIwMTYsIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDIwMTYiLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDIwMTYiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSArIHlsaW0oLTgwLDM1MCkKYGBgCgoKCiMjIyAyMDE3CgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkZm0uMjAxNyA8LSBkZm1fc3Vic2V0KGRmbS50cmltLmJ1ZGdldCwgWWVhcj09MjAxNykKZnJlcS4yMDE3IDwtIHRleHRzdGF0X2ZyZXF1ZW5jeShkZm0uMjAxNykKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGZyZXEuMjAxN1sxOjUwLCBdLCBhZXMoeCA9IHJlb3JkZXIoZmVhdHVyZSwgZnJlcXVlbmN5KSwgeSA9IGZyZXF1ZW5jeSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJGcmVxdWVuY3kiKSArIGdndGl0bGUoIk5CUiAyMDE3OiBUb3AgNTAgbW9zdCBmcmVxdWVudCB3b3JkcyIpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0V9CnRleHRwbG90X3dvcmRjbG91ZChkZm0uMjAxNywgbWF4LndvcmRzPTEwMCwgc2NhbGU9YygyLC41KSwgcmFuZG9tLm9yZGVyPUZBTFNFKQpgYGAKCgpgYGB7ciBlY2hvPUZBTFNFLHJlc3VsdHM9ICJoaWRlIixmaWcua2VlcD0iYWxsIn0Ka2V5bmVzc18yMDE3IDwtIHRleHRzdGF0X2tleW5lc3MoZGZtLnRyaW0uYnVkZ2V0LCBkb2N2YXJzKGJ1ZGdldF9jb3JwdXMsICJZZWFyIikgPT0gMjAxNywgIHNvcnQgPSBUUlVFKQoKdGV4dHBsb3Rfa2V5bmVzcyhrZXluZXNzXzIwMTcsIHNob3dfcmVmZXJlbmNlID0gVFJVRSwgbiA9IDIwTCwgbWluX2NvdW50ID0gMkwpICArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSIiLCBsYWJlbHM9YygiTkJSIDIwMTciLCAiT3RoZXIgTkJScyIpKSArIGdndGl0bGUoIktleW5lc3MgYW5hbHlzaXMgb2YgTkJSIDIwMTciKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjgpKSArIHlsaW0oLTUwLDMwMCkKYGBgCgoKCiMgTGlua2luZyBkZXZlbG9wbWVudCBwbGFucyB3aXRoIE5CUnMKCldlIGNhbiBhc3Nlc3MgdGhlIGxpbmthZ2UgYmV0d2VlbiBkZXZlbG9wbWVudCBwbGFucyBhbmQgTkJScyBieSBjYWxjdWxhdGluZyBzaW1pbGFyaXRpZXMgYmV0d2VlbiBkb2N1bWVudHMuIFRoZSBzaW1wbGVzdCBzaW1pbGFyaXR5IG1lYXN1cmUgYmV0d2VlbiB0d28gZG9jdW1lbnRzIHRoYXQgbm9ybWFsaXNlcyB0aGUgbGVuZ3RoIG9mIHRoZSBkb2N1bWVudHMgZHVyaW5nIGNvbXBhcmlzb24gaXMgY29zaW5lIHNpbWlsYXJpdHkuIEZpcnN0LCB3ZSBub3JtYWxpc2VkIHRoZSBEb2N1bWVudCBGZWF0dXJlIE1hdHJpeCB1c2luZyB0aGUgVEYtSURGICh0ZXJtIGZyZXF1ZW5jeSBpbnZlcnNlIGRvY3VtZW50IGZyZXF1ZW5jeSkgd2VpZ2h0cy4gVGhlIHdlaWdodCBpbmNyZWFzZXMgcHJvcG9ydGlvbmFsbHkgdG8gdGhlIG51bWJlciBvZiB0aW1lcyBhIHRlcm0gYXBwZWFycyBpbiBhIGRvY3VtZW50IGFuZCBvZmZzZXQgYnkgdGhlIGZyZXF1ZW5jeSBvZiB0aGUgd29yZCBpbiB0aGUgY29ycHVzLiBJdCdzIGEgc3RhbmRhcmQgd2VpZ2h0aW5nIHN5c3RlbSBpbiBJbmZvcm1hdGlvbiBSZXRyaWV2YWwgYW5kIGFpbXMgdG8gY2FwdHVyZSB0aGF0IHNvbWUgd29yZHMgYXBwZWFyIG1vcmUgZnJlcXVlbnRseS4gU2Vjb25kLCB3ZSB2aWV3IGRvY3VtZW50cyBhcyBhIHNldCBvZiB2ZWN0b3JzIGluIGEgdmVjdG9yIHNwYWNlLiBUaGUgY29zaW5lIG9mIHRoZSBhbmdsZSBiZXR3ZWVuIHR3byB2ZWN0b3JzIGlzIGEgbWVhc3VyZSBvZiB0aGVpciBzaW1pbGFyaXR5LiBUaGlzIGlzIGEgc3RhbmRhcmQgbWVhc3VyZSBpbiBJbmZvcm1hdGlvbiBSZXRyaWV2YWwuIEluIHRoZXNlIHNldHRpbmdzLCBjb3NpbmUgc2ltaWxhcml0eSByYW5nZXMgYmV0d2VlbiAwIGFuZCAxLCB3aGVyZSAwIG1lYW5zIHRoYXQgZG9jdW1lbnRzIGFyZSBvcnRob2dvbmFsIGFuZCAxIG1lYW5zIHRoZSBkb2N1bWVudHMgYXJlIHRoZSBzYW1lLgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KREFUQV9ESVIgPC0gIi4uL2RhdGEvIiAKCmNvbWJpbmVkX2ZpbGVzIDwtIHJlYWR0ZXh0KHBhc3RlMChEQVRBX0RJUiwgImNvbnZlcnRlZC9jb21iaW5lZC8qIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N2YXJzZnJvbSA9ICJmaWxlbmFtZXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHZzZXA9Il8iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdmFybmFtZXMgPSBjKCJEb2N1bWVudCIsICJDaGFwdGVyIiwgIlllYXIiKSkKCmNvbWJpbmVkX2ZpbGVzJGRvY19pZCA8LSBzdHJfcmVwbGFjZShjb21iaW5lZF9maWxlcyRkb2NfaWQsICIudHh0IiwgIiIpIAoKY29tYmluZWRfY29ycHVzIDwtIGNvcnB1cyhjb21iaW5lZF9maWxlcywgdGV4dF9maWVsZCA9ICJ0ZXh0IiwgZG9jaWRfZmllbGQgPSAiZG9jX2lkIikgCmBgYAoKCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQojVG9rZW5pemF0aW9uIGFuZCBiYXNpYyBwcmUtcHJvY2Vzc2luZwp0b2sgPC0gdG9rZW5zKGNvbWJpbmVkX2NvcnB1cywgd2hhdCA9ICJ3b3JkIiwKICAgICAgICAgICAgICByZW1vdmVfcHVuY3QgPSBUUlVFLAogICAgICAgICAgICAgIHJlbW92ZV9zeW1ib2xzID0gVFJVRSwKICAgICAgICAgICAgICByZW1vdmVfbnVtYmVycyA9IFRSVUUsCiAgICAgICAgICAgICAgcmVtb3ZlX3R3aXR0ZXIgPSBUUlVFLAogICAgICAgICAgICAgIHJlbW92ZV91cmwgPSBUUlVFLAogICAgICAgICAgICAgIHJlbW92ZV9oeXBoZW5zID0gVFJVRSwKICAgICAgICAgICAgICB2ZXJib3NlID0gVFJVRSkKYGBgCgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9Cgp0b2subSA8LSB0b2tlbnNfc2VsZWN0KHRvaywgYygiW1xcZC1dIiwiXi57MSwyfSQiLCAiW1s6cHVuY3Q6XV0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uID0gInJlbW92ZSIsIAogICAgICAgICAgICAgICAgICAgIHZhbHVldHlwZT0icmVnZXgiLCB2ZXJib3NlID0gVFJVRSkKCnRvay5yIDwtIHRva2Vuc190b2xvd2VyKHRvay5tKQoKYGBgCgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CgpkZm0gPC0gZGZtKHRvay5yLCAKICAgICAgICAgICB0b2xvd2VyID0gVFJVRSwKICAgICAgICAgICByZW1vdmU9IGMoc3RvcHdvcmRzKCJTTUFSVCIpLCAiY2VudCIsImJpbGxpb24iKSwKICAgICAgICAgICBzdGVtPVRSVUUsIAogICAgICAgICAgIHZlcmJvc2UgPSBUUlVFKQoKZGZtLnRyaW0gPC0gZGZtX3RyaW0oZGZtLCBtaW5fY291bnQgPSAzKQoKZGZtLmNvbWJpbmVkIDwtIGRmbV9ncm91cChkZm0udHJpbSwgZ3JvdXBzID0gYygiRG9jdW1lbnQiLCAiWWVhciIpKQoKZGZtLncgPC0gZGZtX3dlaWdodChkZm0uY29tYmluZWQsIHR5cGUgPSAidGZpZGYiKQoKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0Kc2ltaWwgPC0gdGV4dHN0YXRfc2ltaWwoZGZtLncsIG1ldGhvZCA9ICJjb3NpbmUiLCBtYXJnaW4gPSAiZG9jdW1lbnRzIikKCnNpbWlsYXJpdHkgPC0gYXMuZGF0YS5mcmFtZShhcy5tYXRyaXgoc2ltaWwpKSAlPiUgCiAgc2VsZWN0KFJEUC4xOTk0LCBHRUFSLjE5OTYsIEFzZ2lTQS4yMDA2LCBOR1AuMjAxMCwgTkRQLjIwMTIpIAogIApzaW1pbGFyaXR5JGRvY3MgPC0gIHJvdy5uYW1lcyhzaW1pbGFyaXR5KQoKc2ltaWxhcml0eSA8LSBzdWJzZXQoc2ltaWxhcml0eSwgc3RyX2RldGVjdChzaW1pbGFyaXR5JGRvY3MsICJOQlIqIikpCnNpbWlsYXJpdHkkWWVhciA8LSBhcy5udW1lcmljKHN0cl9leHRyYWN0KHNpbWlsYXJpdHkkZG9jcywgIlxcZCsiKSkKYGBgCgpUaGUgdGFibGVzIGFuZCBwbG90cyBiZWxvdyBwcm92aWRlIGNvc2luZSBzaW1pbGFyaXR5IG1lYXN1cmVzIGZvciBlYWNoIGRldmVsb3BtZW50IHBsYW4gYW5kIGZ1bGwgc2V0IG9mIE5hdGlvbmFsIEJ1ZGdldCBSZXZpZXdzLgoKIyMgUkRQCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0KcmRwIDwtIHNlbGVjdChzaW1pbGFyaXR5LCBSRFAuMTk5NCkgCnJkcCRSRFAuMTk5NCA8LSByb3VuZChyZHAkUkRQLjE5OTQsIGRpZ2l0cyA9NCkKcmRwIDwtIGRhdGEudGFibGU6OnNldG9yZGVyKHJkcCwgLVJEUC4xOTk0KQoKcGFuZGVyOjpwYW5kb2MudGFibGUocmRwKQpgYGAKKyBzY2FsZV94X2Rpc2NyZXRlKGJyZWFrcz1jKCIwLjUiLCIxIiwiMiIpLAogICAgICAgIGxhYmVscz1jKCJEb3NlIDAuNSIsICJEb3NlIDEiLCAiRG9zZSAyIikpCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QoZGF0YT1zaW1pbGFyaXR5LCBhZXMoeD1ZZWFyLCB5PVJEUC4xOTk0LCBncm91cD0xKSkgKwogIGdlb21fbGluZSgpKyAKICBnZW9tX3BvaW50KCkgKyBnZ3RpdGxlKCJSRFAiKSArIHlsYWIoIkNvc2luZSBzaW1pbGFyaXR5IikgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9YygyMDA2LDIwMTAsMjAxMiksbGluZXR5cGU9ImRhc2hlZCIsIGNvbG91ciA9ICJyZWQiKSsKICBzY2FsZV94X2Rpc2NyZXRlKG5hbWUgPSJOYXRpb25hbCBCdWRnZXQgUmV2aWV3IiwgbGltaXRzPXNlcSgxOTk4LDIwMTcsMiksCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiMTk5OCIsICIyMDAwIiwgIjIwMDIiLCAiMjAwNCIsIkFzZ2lTQSIsICIyMDA4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOR1AiLCAiTkRQIiwgIjIwMTQiLCAiMjAxNiIpKQpgYGAKCgojIyBHRUFSCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0KZ2VhciA8LSBzZWxlY3Qoc2ltaWxhcml0eSwgR0VBUi4xOTk2KSAKZ2VhciRHRUFSLjE5OTYgPC0gcm91bmQoZ2VhciRHRUFSLjE5OTYsIGRpZ2l0cyA9NCkKZ2VhciA8LSBkYXRhLnRhYmxlOjpzZXRvcmRlcihnZWFyLCAtR0VBUi4xOTk2KQoKcGFuZGVyOjpwYW5kb2MudGFibGUoZ2VhcikKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGRhdGE9c2ltaWxhcml0eSwgYWVzKHg9WWVhciwgeT1HRUFSLjE5OTYsIGdyb3VwPTEpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpICsgZ2d0aXRsZSgiR0VBUiIpICsgeWxhYigiQ29zaW5lIHNpbWlsYXJpdHkiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD1jKDIwMDYsMjAxMCwyMDEyKSxsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3VyID0gInJlZCIpKwogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9Ik5hdGlvbmFsIEJ1ZGdldCBSZXZpZXciLCBsaW1pdHM9c2VxKDE5OTgsMjAxNywyKSwKICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCIxOTk4IiwgIjIwMDAiLCAiMjAwMiIsICIyMDA0IiwiQXNnaVNBIiwgIjIwMDgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5HUCIsICJORFAiLCAiMjAxNCIsICIyMDE2IikpCmBgYAoKIyMgQXNnaVNBCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0KYXNnaXNhIDwtIHNlbGVjdChzaW1pbGFyaXR5LCBBc2dpU0EuMjAwNikgCmFzZ2lzYSRBc2dpU0EuMjAwNiA8LSByb3VuZChhc2dpc2EkQXNnaVNBLjIwMDYsIGRpZ2l0cyA9NCkKYXNnaXNhIDwtIGRhdGEudGFibGU6OnNldG9yZGVyKGFzZ2lzYSwgLUFzZ2lTQS4yMDA2KQoKcGFuZGVyOjpwYW5kb2MudGFibGUoYXNnaXNhKQpgYGAKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdChkYXRhPXNpbWlsYXJpdHksIGFlcyh4PVllYXIsIHk9QXNnaVNBLjIwMDYsIGdyb3VwPTEpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpICsgZ2d0aXRsZSgiQXNnaVNBIikgKyB5bGFiKCJDb3NpbmUgc2ltaWxhcml0eSIpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PWMoMjAwNiwyMDEwLDIwMTIpLGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvdXIgPSAicmVkIikrCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0iTmF0aW9uYWwgQnVkZ2V0IFJldmlldyIsIGxpbWl0cz1zZXEoMTk5OCwyMDE3LDIpLAogICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIjE5OTgiLCAiMjAwMCIsICIyMDAyIiwgIjIwMDQiLCJBc2dpU0EiLCAiMjAwOCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkdQIiwgIk5EUCIsICIyMDE0IiwgIjIwMTYiKSkKYGBgCgojIyBOR1AKCmBgYHtyIGVjaG89RkFMU0UsIHJlc3VsdHM9ImFzaXMifQpuZ3AgPC0gc2VsZWN0KHNpbWlsYXJpdHksIE5HUC4yMDEwKSAKbmdwJE5HUC4yMDEwIDwtIHJvdW5kKG5ncCROR1AuMjAxMCwgZGlnaXRzID00KQpuZ3AgPC0gZGF0YS50YWJsZTo6c2V0b3JkZXIobmdwLCAtTkdQLjIwMTApCgpwYW5kZXI6OnBhbmRvYy50YWJsZShuZ3ApCmBgYAoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGRhdGE9c2ltaWxhcml0eSwgYWVzKHg9WWVhciwgeT1OR1AuMjAxMCwgZ3JvdXA9MSkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkgKyBnZ3RpdGxlKCJOR1AiKSArIHlsYWIoIkNvc2luZSBzaW1pbGFyaXR5IikgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9YygyMDA2LDIwMTAsMjAxMiksbGluZXR5cGU9ImRhc2hlZCIsIGNvbG91ciA9ICJyZWQiKSsKICBzY2FsZV94X2Rpc2NyZXRlKG5hbWUgPSJOYXRpb25hbCBCdWRnZXQgUmV2aWV3IiwgbGltaXRzPXNlcSgxOTk4LDIwMTcsMiksCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiMTk5OCIsICIyMDAwIiwgIjIwMDIiLCAiMjAwNCIsIkFzZ2lTQSIsICIyMDA4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOR1AiLCAiTkRQIiwgIjIwMTQiLCAiMjAxNiIpKQpgYGAKCiMjIE5EUAoKYGBge3IgZWNobz1GQUxTRSwgcmVzdWx0cz0iYXNpcyJ9Cm5kcCA8LSBzZWxlY3Qoc2ltaWxhcml0eSwgTkRQLjIwMTIpIApuZHAkTkRQLjIwMTIgPC0gcm91bmQobmRwJE5EUC4yMDEyLCBkaWdpdHMgPTQpCm5kcCA8LSBkYXRhLnRhYmxlOjpzZXRvcmRlcihuZHAsIC1ORFAuMjAxMikKCnBhbmRlcjo6cGFuZG9jLnRhYmxlKG5kcCkKYGBgCgoKYGBge3IgZWNobz1GQUxTRX0KZ2dwbG90KGRhdGE9c2ltaWxhcml0eSwgYWVzKHg9WWVhciwgeT1ORFAuMjAxMiwgZ3JvdXA9MSkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkgKyBnZ3RpdGxlKCJORFAiKSArIHlsYWIoIkNvc2luZSBzaW1pbGFyaXR5IikgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9YygyMDA2LDIwMTAsMjAxMiksbGluZXR5cGU9ImRhc2hlZCIsIGNvbG91ciA9ICJyZWQiKSsKICBzY2FsZV94X2Rpc2NyZXRlKG5hbWUgPSJOYXRpb25hbCBCdWRnZXQgUmV2aWV3IiwgbGltaXRzPXNlcSgxOTk4LDIwMTcsMiksCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiMTk5OCIsICIyMDAwIiwgIjIwMDIiLCAiMjAwNCIsIkFzZ2lTQSIsICIyMDA4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOR1AiLCAiTkRQIiwgIjIwMTQiLCAiMjAxNiIpKQpgYGAKCgojIFJlZmVyZW5jZXMKCi0gU2lldmVydCwgQy4gYW5kIEsuIFNoaXJsZXkuICJMREF2aXM6IEEgbWV0aG9kIGZvciB2aXN1YWxpemluZyBhbmQgaW50ZXJwcmV0aW5nIHRvcGljcy4iIFByb2NlZWRpbmdzIG9mIHRoZSBXb3Jrc2hvcCBvbiBJbnRlcmFjdGl2ZSBMYW5ndWFnZSBMZWFybmluZywgVmlzdWFsaXphdGlvbiwgYW5kIEludGVyZmFjZXMsIHBhZ2VzIDYz4oCTNzAsIEJhbHRpbW9yZSwgTWFyeWxhbmQsIFVTQSwgSnVuZSAyNywgMjAxNC4KCi0gSm9uYXRoYW4gTS4gQmlzY2hvZiBhbmQgRWRvYXJkbyBNLiBBaXJvbGRpLiAyMDEyLiAiU3VtbWFyaXppbmcgdG9waWNhbCBjb250ZW50IHdpdGggd29yZCBmcmVxdWVuY3kgYW5kIGV4Y2x1c2l2aXR5Ii4gSUNNTC4KCi0gRGF2aWQgTS4gQmxlaSwgVGhvbWFzIEwuIEdyaWZmaXRocywgTWljaGFlbCBJLiBKb3JkYW4sIGFuZCBKb3NodWEgQi4gVGVuZW5iYXVtLiAyMDAzLiAiSGllcmFyY2hpY2FsIFRvcGljIE1vZGVscyBhbmQgdGhlIE5lc3RlZCBDaGluZXNlIFJlc3RhdXJhbnQgUHJvY2Vzcy4iIE5JUFMuCgotIERhdmlkIE1pbW5vLCBIYW5uYSBNLiBXYWxsYWNoLCBFZG11bmQgVGFsbGV5LCBNaXJpYW0gTGVlbmRlcnMsIGFuZCBBbmRyZXcgTWNDYWxsdW0uIDIwMTEuICJPcHRpbWl6aW5nIFNlbWFudGljIENvaGVyZW5jZSBpbiBUb3BpYyBNb2RlbHMuIiBFTU5MUC4KCi0gTWF0dGhldyBBLiBUYWRkeSAyMDExLiAiT24gRXN0aW1hdGlvbiBhbmQgU2VsZWN0aW9uIGZvciBUb3BpYyBNb2RlbHMuIiBBSVNUQVRTLgoKLSBSb2JlcnRzLCBNYXJnYXJldCBFLCBCcmFuZG9uIE0gU3Rld2FydCBhbmQgRWRvYXJkbyBNIEFpcm9sZGkuIDIwMTYuICJBIG1vZGVsIG9mIHRleHQgZm9yIGV4cGVyaW1lbnRhdGlvbiBpbiB0aGUgc29jaWFsIHNjaWVuY2VzLiIgSm91cm5hbCBvZiB0aGUgQW1lcmljYW4gU3RhdGlzdGljYWwgQXNzb2NpYXRpb24gMTExKDUxNSk6OTg4LTEwMDMuCgotIEFpcm9sZGksIEVNIGFuZCBKTSBCaXNjaG9mLiAiSW1wcm92aW5nIGFuZCBldmFsdWF0aW5nIHRvcGljIG1vZGVscyBhbmQgb3RoZXIgbW9kZWxzIG9mIHRleHQgKHdpdGggZGlzY3Vzc2lvbikuIiBKb3VybmFsIG9mIHRoZSBBbWVyaWNhbiBTdGF0aXN0aWNhbCBBc3NvY2lhdGlvbiAxMTEgKDUxNiksIDEzODEtMTQwMy4KCgo=